题意:最快出去的路径
题解:一看就是一个很简单的最短路,用优先队列写个spfa就过了,但是没想到水了个(n*n)^2的算法也过了。。。愿意很简单,因为是个稀疏图
敲完以后一百度发现就是个简单的bfs+优先队列其实思路是一样的,每次选出不在路径中距离路径最短的边,因为这个更新的时候只能更新其周围的四个点,那个吗。。。懒得打了,。。。记得提醒我有时间打一下。。。。
代码:转化成图后,单源最短路求到n*m-1就可以了,完美
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N = 111; 6 #define INF 0x1fffffff 7 char mp[N][N]; 8 int dist[N*N]; 9 bool p[N*N]; 10 int head[N*N]; 11 struct Edge{ 12 int to; 13 int next; 14 int w; 15 }edge[N*N*10]; 16 int Ecnt; 17 void init() 18 { 19 Ecnt = 0; 20 memset(head,-1,sizeof(head)); 21 } 22 23 void printTree(int n, int m){ 24 for(int i = 0; i < n*m; i++) { 25 printf("%d: ", i); 26 for(int j = head[i]; j != -1; j = edge[j].next) { 27 printf("to = %d w = %d", edge[j].to,edge[j].w); 28 } 29 puts(""); 30 } 31 } 32 33 void add(int from, int to, int w){ 34 edge[Ecnt].to = to; 35 edge[Ecnt].w = w; 36 edge[Ecnt].next = head[from]; 37 head[from]=Ecnt++; 38 } 39 int go[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; 40 bool in(int x,int y,int n, int m){ 41 if(x<n&&x>=0&&y<m&&y>=0) return true; 42 else return false; 43 } 44 int ans[N*N]; 45 int fa[N*N]; 46 int sum[N*N]; 47 void f(int n, int m){ 48 int t = 0; 49 int tm = n*m-1; 50 sum[t++] = n*m-1; 51 while(fa[tm]!=0){ 52 sum[t++] = fa[tm]; 53 tm = fa[tm]; 54 } 55 for(int i = t-1; i >= 0; i--){ 56 ans[t-i] = sum[i]; 57 } 58 } 59 int Count; 60 void dijk(int s, int n) 61 { 62 63 int i , j , k ; 64 Count = 0; 65 for(i = 0 ;i <= n ;i++) 66 { 67 p[i] = false; 68 dist[i] = INF; 69 } 70 //p[s] = true; 71 dist[s] = 0; 72 73 for( i = 0; i < n ; i++) 74 { 75 int Min = INF ; 76 k = 0 ; 77 for( j = 0 ; j < n ; j++) 78 { 79 if(!p[j]&&dist[j]<Min) 80 { 81 Min = dist[j]; 82 k = j; 83 } 84 } 85 86 if(Min == INF) return ; 87 p[k] = true; 88 //printf("k = %d ",k); 89 for(j = head[k]; j != -1 ; j = edge[j].next) 90 { 91 Edge e = edge[j]; 92 if(!p[e.to]&&dist[e.to]>dist[k]+e.w){ 93 dist[e.to] = dist[k]+e.w; 94 fa[e.to] = k; 95 } 96 } 97 } 98 } 99 int main() 100 { 101 int n,m; 102 while(~scanf("%d%d",&n,&m)) 103 { 104 for(int i = 0; i < n; i++){ 105 scanf("%s",&mp[i]); 106 } 107 int id; 108 init(); 109 for(int i = 0; i < n; i++){ 110 for(int j = 0; j < m; j++){ 111 id = i*m+j; 112 for(int k= 0; k < 4; k++){ 113 int tx = i+go[k][0]; 114 int ty = j+go[k][1]; 115 int tid = tx*m+ty; 116 if(in(tx,ty,n,m)){ 117 if(mp[tx][ty]=='.') add(id,tid,1); 118 else if(mp[tx][ty]=='X');//add(id,tid,INF); 119 else add(id,tid,mp[tx][ty]-'0'+1); 120 } 121 } 122 } 123 } 124 // printTree(n,m); 125 int cnt = 1; 126 int c = (n)*(m); 127 dijk(0,c); 128 f(n,m); 129 130 int t = 0; 131 if(dist[c-1]==INF) { 132 printf("God please help our poor hero. FINISH "); 133 continue; 134 } 135 printf("It takes %d seconds to reach the target position, let me show you the way. ",dist[c-1]); 136 for(int i = 1;cnt <= dist[c-1] ; i++){ 137 int sx,sy,dx,dy; 138 sx = ans[t]/(m); 139 sy = ans[t++]%(m); 140 dx = ans[t]/(m); 141 dy = ans[t]%(m); 142 printf("%ds:(%d,%d)->(%d,%d) ",cnt++,sx,sy,dx,dy); 143 if(mp[dx][dy]!='.') { 144 for(int i = 0; i < (mp[dx][dy]-'0');i++) 145 printf("%ds:FIGHT AT (%d,%d) ",cnt++,dx,dy); 146 } 147 } 148 puts("FINISH"); 149 } 150 return 0; 151 }