Here We Go(relians) Again hdu 2722
來源:互聯網
上載者:User
/*<br />題目其實很簡單,只是題目太長了,看懂有點不容易,最鬱悶的是以開始就看懂了的,<br />只是2520/8 = 290 了,結果導致自己看懂的想法徹底崩潰,於是就在糾結中掙紮,痛苦ing。。<br />沒想到這麼弱智的毛病也犯<br />題目大致意思從起點到終點找一條花費時間最少的路,並輸出(blips其實就是時間)<br />每條路的距離是2520 (是1 到 9的最小公倍數 可以不管的), 給你兩點之間最大速度 P<br />兩點的時間 t = 2520 / p;注意 p = 0的是,兩點為斷路,接下來就是構圖共有 v = n * ( m + 1) + m 個點<br />*/<br />#include <iostream><br />#include <cstdio><br />#include <queue><br />#include <cstring><br />using namespace std;</p><p>const int INF = 0x3fffffff;<br />const int N = 1005;<br />int cost[N][N];<br />int dis[N];<br />bool hash[N];</p><p>struct node<br />{<br />int dis;<br />int num;<br />friend bool operator < (node a, node b)<br />{<br />return a.dis > b.dis;<br />}<br />};</p><p>void BFS(int end)<br />{<br />memset(hash, false, sizeof(hash));<br />node P, F;<br />priority_queue <node> Q;<br />for(int i = 1; i <= end; i++)<br />{<br />dis[i] = cost[0][i];<br />if(dis[i] != INF)<br />{<br />P.num = i;<br />P.dis = dis[i];<br />Q.push(P);<br />}<br />}<br />hash[0] = true;<br />while(!Q.empty())<br />{<br />F = Q.top();<br />Q.pop();<br />if(hash[end])<br />break;<br />hash[F.num] = true;<br />for(int i = 1; i <= end; i++)<br />{<br />if(!hash[i] && dis[i] > F.dis + cost[F.num][i] && cost[F.num][i] != INF)<br />{<br />dis[i] = F.dis + cost[F.num][i];<br />P.num = i;<br />P.dis = dis[i];<br />Q.push(P);<br />}</p><p>}<br />}<br />}</p><p>inline int direction_w_e(char s[])<br />{<br />if(s[0] == '*')<br />return 2;<br />if(s[0] == '>')<br />return 1;<br />if(s[0] == '<')<br />return -1;<br />}</p><p>inline int direction_n_s(char s[])<br />{<br />if(s[0] == '*')<br />return 2;<br />if(s[0] == '^')<br />return 1;<br />if(s[0] == 'v')<br />return -1;<br />}</p><p>inline void Int()<br />{<br />for(int i = 0 ;i < N; i++)<br />for(int j = 0; j < N; j++)<br />{<br />if(i == j)<br />cost[i][j] = 0;<br />else<br />cost[i][j] = INF;<br />}<br />}</p><p>int main()<br />{<br />int n, m;<br />while(scanf("%d %d", &n, &m) != EOF )<br />{<br />if(n == 0 && m == 0 )<br />break;<br />int sp, p;<br />char s[2];<br />int dir;<br />int M = m + 1;<br />Int();<br />//以下是構圖很麻煩,用鄰接表很應該簡單點的,要學習下。。<br />for(int i = 0; i <= n; i++)<br />{<br />if(i == 0)<br />{<br />for(int j = 1; j <= m; j++)<br />{<br />scanf("%d %s", &p, s);<br />if(p == 0)<br />{<br />cost[j - 1][j] = cost[j][j - 1] = INF;<br />continue;<br />}<br /> sp = 2520 / p;<br />dir = direction_w_e(s);<br />if(dir == 2)<br />cost[j - 1][j] = cost[j][j - 1] = sp;<br />if(dir == -1)<br />cost[j][j - 1] = sp;<br />if(dir == 1)<br />cost[j - 1][j] = sp;</p><p>}<br />}<br />else<br />{<br />for(int j = 0; j <= m; j++)<br />{<br />scanf("%d %s", &p, s);<br />if(p == 0)<br />{<br />cost[(i - 1) * M + j][ M * i + j] = cost[M * i + j][M * (i - 1) + j] = INF;<br />continue;<br />}<br />sp = 2520 / p;<br />dir = direction_n_s(s);<br />if(dir == 2)<br />cost[(i - 1) * M + j][ M * i + j] = cost[M * i + j][M * (i - 1) + j] = sp;<br />if(dir == -1)<br />cost[(i - 1) * M + j][ M * i + j] = sp;<br />if(dir == 1)<br />cost[M * i + j][M * (i - 1) + j] = sp;</p><p>}<br />for(int j = 1; j <= m; j++)<br />{<br />scanf("%d %s", &p, s);<br />if(p == 0)<br />{<br />cost[M * i + j][M * i + j -1] = cost[M * i + j -1][M * i + j] = INF;<br />continue;<br />}<br />sp = 2520 / p;<br />dir = direction_w_e(s);<br />if(dir == 2)<br />cost[M * i + j][M * i + j -1] = cost[M * i + j -1][M * i + j] = sp;<br />if(dir == -1)<br />cost[M * i + j][M * i + j -1] = sp;<br />if(dir == 1)<br />cost[M * i + j -1][M * i + j] = sp;<br />if(sp == 0)<br />cost[M * i + j][M * i + j -1] = cost[M * i + j -1][M * i + j] = INF;<br />}<br />}<br />}<br />int end = n * M + m;<br />BFS(end);<br />if(dis[end] != INF)<br />printf("%d blips/n", dis[end]);<br />else<br />printf("Holiday/n");<br />}<br />}</p><p>/*<br />#include <iostream><br />#include <cstdio><br />#include <algorithm><br />#include <memory.h><br />#include <cmath><br />#include <bitset><br />#include <queue><br />#include <vector><br />using namespace std;<br />const int border = (1<<20)-1;const int maxsize = 37;const int maxn = 1105;const int inf = 1000000000;#define clr(x,y) memset(x,y,sizeof(x))#define add(x) x=((x+1)&border)#define in(x) scanf("%d",&x)#define out(x) printf("%d/n",x)#define min(m,v) (m)<(v)?(m):(v)#define max(m,v) (m)>(v)?(m):(v)#define abs(x) ((x)>0?(x):-(x))#define len 2520#define set_node(no,a,b) {no.u=a;no.val=b;}typedef struct{ int v,next; int val;}edge;typedef struct{ int u; int val;}node;bool operator < (const node& a,const node& b){ return a.val > b.val;}edge edge[maxn*maxn];int n,m,start,end,index;int dist[maxn],net[maxn];bool visit[maxn];void add_edge(const int& u,const int& v,const int& sp){ edge[index].v = v; edge[index].next = net[u]; edge[index].val = sp; net[u] = index++;}void add_input(const int& u,const int& v,const int& sp,const char& c){ if(c=='*') { add_edge(u,v,sp); add_edge(v,u,sp); return ; } if( c == '>' || c=='v') add_edge(u,v,sp); else add_edge(v,u,sp);}int init(){ index = 0; clr(net,-1); clr(visit,0); clr(dist,127); return 0;}int input(){ int i,j,u,v,tmp,sp; char ch; for(i = 0; i < n-1; ++i) { for(j = 0; j < m-1; ++j) { scanf("%d %c",&sp,&ch); if(sp == 0) continue; u = i*m + j; v = u + 1; add_input(u,v,sp,ch); } for(j = 0; j < m; ++j) { scanf("%d %c",&sp,&ch); if(sp == 0) continue; u = i*m + j; v = (i+1)*m + j; add_input(u,v,sp,ch); } } for(j = 0; j < m-1; ++j) { scanf("%d %c",&sp,&ch); u = (n-1)*m + j; v = u + 1; if(sp == 0) continue; add_input(u,v,sp,ch); } return 0;}int dij(){ int i,j,u,tmp,mark,mmin,v; int n = n*m; priority_queue<node> que; node node,t_node; while(!que.empty()) que.pop(); set_node(t_node,0,0); que.push(t_node); dist[0] = 0; clr(visit,0); while(!que.empty()) { node = que.top(); que.pop(); u = node.u; if(visit[node.u]) continue; if(u == n-1) return node.val; visit[u] = true; for(i = net[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(visit[v]) continue; tmp = dist[u] + len/edge[i].val; if(dist[v] > tmp) { dist[v] = tmp; set_node(t_node,v,tmp); que.push(t_node); } } } return -1;}int work(){ int i,j,ans; ans = dij(); if(ans == -1) printf("holiday/n"); else printf("%d blips/n",ans); return 0;}int main(){ while(scanf("%d%d",&n,&m)) { if(!n && !m) break; ++n,++m; init(); input(); work(); } return 0;}o(n^2):</p><p>#include <iostream>#include <cstdio>#include <algorithm>#include <memory.h>#include <cmath>#include <bitset>#include <queue>#include <vector>using namespace std;const int border = (1<<20)-1;const int maxsize = 37;const int maxn = 1105;const int inf = 1000000000;#define clr(x,y) memset(x,y,sizeof(x))#define add(x) x=((x+1)&border)#define in(x) scanf("%d",&x)#define out(x) printf("%d/n",x)#define min(m,v) (m)<(v)?(m):(v)#define max(m,v) (m)>(v)?(m):(v)#define abs(x) ((x)>0?(x):-(x))#define len 2520typedef struct{ int v,next; int val;}edge;typedef struct{ int u; int val;}node;bool operator < (const node& a,const node& b){ return a.val > b.val;}edge edge[maxn*maxn];int n,m,start,end,index;int dist[maxn],net[maxn];bool visit[maxn];void add_edge(const int& u,const int& v,const int& sp){ edge[index].v = v; edge[index].next = net[u]; edge[index].val = sp; net[u] = index++;}void add_input(const int& u,const int& v,const int& sp,const char& c){ if(c=='*') { add_edge(u,v,sp); add_edge(v,u,sp); return ; } if( c == '>' || c=='v') add_edge(u,v,sp); else add_edge(v,u,sp);}int init(){ index = 0; clr(net,-1); clr(visit,0); clr(dist,127); return 0;}int input(){ int i,j,u,v,tmp,sp; char ch; for(i = 0; i < n-1; ++i) { for(j = 0; j < m-1; ++j) { //cin>>sp>>ch; scanf("%d %c",&sp,&ch); if(sp == 0) continue; u = i*m + j; v = u + 1; add_input(u,v,sp,ch); } for(j = 0; j < m; ++j) { //cin>>sp>>ch; scanf("%d %c",&sp,&ch); if(sp == 0) continue; u = i*m + j; v = (i+1)*m + j; add_input(u,v,sp,ch); } } for(j = 0; j < m-1; ++j) { //cin>>sp>>ch; scanf("%d %c",&sp,&ch); u = (n-1)*m + j; v = u + 1; if(sp == 0) continue; add_input(u,v,sp,ch); } return 0;}int dij(){ int i,j,tmp,mark,mmin,v; int n = n*m; dist[0] = 0; clr(visit,0); for(i = 0; i < n; ++i) { mmin = inf; for(j = 0; j < n; ++j) if(!visit[j] && mmin > dist[j]) { mmin = dist[j]; mark = j; } visit[mark] = true; for(j = net[mark]; j != -1; j = edge[j].next) { tmp = len/edge[j].val; v = edge[j].v; if(!visit[v] && dist[v] > tmp + mmin) { dist[v] = tmp + mmin; } } } if(dist[n-1] > inf) return -1; return dist[n-1];}int work(){ int i,j,ans; ans = dij(); if(ans == -1) printf("holiday/n"); else printf("%d blips/n",ans); return 0;}int main(){ while(scanf("%d%d",&n,&m)) { if(!n && !m) break; ++n,++m; init(); input(); work(); } return 0;}<br />*/