最短路
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 41510 Accepted Submission(s): 18133
Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
Input
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
输入保证至少存在1条商店到赛场的路线。
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
Sample Input
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
Sample Output
3
2
Source
Recommend
//Spfa:无向图建图, 使用邻接表时要注意边数。
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 using namespace std; 6 const int INF = 0x3f3f3f3f; 7 int dis[110], vis[110]; 8 struct Edge 9 { 10 int from, to, w, next; 11 } edge[10010*2]; 12 int head[110], n, m, cnt; 13 void Add(int a, int b, int c) /*******************************/ 14 { 15 edge[cnt].to = b; 16 edge[cnt].w = c; 17 edge[cnt].next = head[a]; 18 head[a] = cnt++; 19 } 20 void add(int a, int b, int c) 21 { 22 Edge E = {a, b, c, head[a]}; 23 edge[cnt] = E; 24 head[a] = cnt++; 25 } /*********************************/ 26 void Spfa(int a) 27 { 28 queue<int> q; 29 memset(vis, 0, sizeof(vis)); 30 for(int i = 1; i <= n; i++) 31 dis[i] = INF; 32 dis[a] = 0; vis[a] = 1; 33 q.push(a); 34 while(!q.empty()) 35 { 36 37 int u = q.front(); 38 q.pop(); 39 vis[u] = 0; 40 for(int i = head[u]; i != -1; i = edge[i].next) 41 { 42 int v = edge[i].to; 43 if(dis[v] > dis[u] + edge[i].w) 44 { 45 dis[v] = dis[u] + edge[i].w; 46 if(!vis[v]) 47 { 48 vis[v] = 1; 49 q.push(v); 50 } 51 } 52 } 53 } 54 printf("%d ", dis[n]); 55 } 56 int main() 57 { 58 while(scanf("%d %d", &n, &m), n+m) 59 { 60 cnt = 0; 61 memset(head, -1, sizeof(head)); 62 int u, v, w; 63 for(int i = 1; i <= m; i++) 64 { 65 scanf("%d %d %d", &u, &v, &w); 66 Add(u, v, w); 67 Add(v, u, w); 68 } 69 Spfa(1); 70 } 71 return 0; 72 }
//Floyd:
1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 5 const int INF = 0x3f3f3f3f; 6 7 int map[110][110]; 8 int i, j, k, n, m; 9 10 void Floyd() 11 { 12 for(k=1; k<=n; k++) 13 for(i=1; i<=n; i++) 14 for(j=1; j<=n; j++) 15 if(map[i][j] > map[i][k] + map[k][j]) 16 map[i][j] = map[i][k] + map[k][j]; 17 printf("%d ", map[1][n]); 18 } 19 int main() 20 { 21 while(~scanf("%d %d", &n, &m)) 22 { 23 if(n==0 && m==0) 24 break; 25 for(i=1; i<=n; i++) 26 for(j=1; j<=n; j++) 27 map[i][j] = (i==j?0:INF); 28 int u, v, w; 29 for(i=1; i<=m; i++){ 30 scanf("%d %d %d", &u, &v, &w); 31 if(map[u][v] > w) 32 map[u][v]=map[v][u]=w; 33 } 34 Floyd(); 35 } 36 return 0; 37 }
//Dijkstra:
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 6 const int INF = 0x3f3f3f3f; 7 int map[110][110], vis[110], dis[110]; 8 int i, j, n, m; 9 10 void Dijkstra(int arc) 11 { 12 memset(vis, 0, sizeof(vis)); 13 for(i=1; i<=n; i++) 14 dis[i] = map[1][i]; 15 vis[arc]=1; 16 for(i=1; i<n; i++) 17 { 18 int min = INF, temp; 19 for(j=1; j<=n; j++){ 20 if(!vis[j] && dis[j] < min){ 21 temp = j; 22 min = dis[j]; 23 } 24 } 25 vis[temp] = 1; 26 for(j=1; j<=n; j++){ 27 if(!vis[j] && dis[j] > dis[temp] + map[temp][j]) 28 dis[j]=dis[temp] + map[temp][j]; 29 30 } 31 } 32 //if(dis[n] == INF) 33 // printf("-1 "); 34 //else 35 printf("%d ", dis[n]); 36 } 37 38 int main() 39 { 40 while(~scanf("%d %d", &n, &m)) 41 { 42 if(n==0 && m==0) 43 break; 44 for(i=1; i<=n; i++) 45 for(j=1; j<=n; j++) 46 map[i][j] = (i==j?0:INF); 47 int u, v, w; 48 for(i=0; i<m; i++){ 49 scanf("%d %d %d", &u, &v, &w); 50 if(map[u][v] > w) 51 map[u][v]=map[v][u]=w; 52 } 53 Dijkstra(1); 54 } 55 return 0; 56 }