Problem Description
某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
Input
本题目包含多组数据,请处理到文件结束。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
Output
对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.
Sample Input
3 3 0 1 1 0 2 3 1 2 1 0 2 3 1 0 1 1 1 2
Sample Output
2 -1
dijkstra代码:
1 #include <stdio.h> 2 #define N 210 3 #define INF 100000000 4 int n, m; 5 int vis[N], dis[N], cost[N][N]; 6 int min(int x, int y) 7 { 8 return x < y ? x : y; 9 } 10 void dijkstra(int s, int t) 11 { 12 int u, v; 13 for(u = 0; u < n; u++) 14 { 15 vis[u] = 0; 16 dis[u] = INF; 17 } 18 dis[s] = 0; 19 while(true) 20 { 21 v = -1; 22 for(u = 0; u < n; u++) 23 if(!vis[u] && (v == -1 || dis[u]<dis[v])) 24 v = u; 25 if(v == -1) 26 break; 27 vis[v] = 1; 28 for(u = 0; u < n; u++) 29 dis[u] = min(dis[u], dis[v]+cost[v][u]); 30 if(v == t) 31 break; 32 } 33 if(dis[t] == INF) 34 printf("-1 "); 35 else 36 printf("%d ", dis[t]); 37 return ; 38 } 39 int main() 40 { 41 int s, t; 42 while(~scanf("%d%d", &n, &m)) 43 { 44 //if(n<0 || n>=200 || m<0 || m>= 1000) 45 // break; 46 int i, j, a, b, c; 47 for(i = 0; i < n; i++) 48 for(j = 0; j < n; j++) 49 cost[i][j] = INF; 50 while(m --) 51 { 52 scanf("%d%d%d", &a, &b, &c); 53 if(cost[a][b] > c) 54 cost[a][b] = cost[b][a] = c; 55 } 56 scanf("%d%d", &s, &t); 57 dijkstra(s, t); 58 } 59 return 0; 60 }
spfa代码:
1 #include <stdio.h> 2 #include <queue> 3 #include <string.h> 4 #define INF 0x3f3f3f3f 5 using namespace std; 6 int n, m, cnt, t; 7 int vis[210], used[210], dis[210]; 8 int head[210]; 9 struct node 10 { 11 int from, to, val, next; 12 }edge[1010]; 13 int add(int x, int y, int z) 14 { 15 edge[cnt].from = x; 16 edge[cnt].to = y; 17 edge[cnt].val = z; 18 edge[cnt].next = head[x]; 19 head[x] = cnt++; 20 } 21 void spfa(int s) 22 { 23 priority_queue <int> q; 24 memset(vis, 0, sizeof(vis)); 25 memset(dis, INF, sizeof(dis)); 26 memset(used, 0, sizeof(used)); 27 vis[s] = 1; 28 dis[s] = 0; 29 q.push(s); 30 while(!q.empty()) 31 { 32 int x = q.top(); 33 q.pop(); 34 vis[x] = 0; 35 for(int i = head[x]; i != -1; i = edge[i].next) 36 { 37 int y = edge[i].to; 38 if(dis[y] > dis[x]+edge[i].val) 39 { 40 dis[y] = dis[x]+edge[i].val; 41 q.push(y); 42 vis[y] = 1; 43 used[y]++; 44 if(used[y] > n) 45 return ; 46 } 47 } 48 } 49 if(q.empty()) 50 { 51 if(dis[t]==INF) 52 printf("-1 "); 53 else 54 printf("%d ", dis[t]); 55 } 56 return ; 57 } 58 int main() 59 { 60 int s, a, b, x; 61 while(~scanf("%d%d", &n, &m)) 62 { 63 cnt = 0; 64 memset(head, -1, sizeof(head)); 65 while(m--) 66 { 67 scanf("%d%d%d", &a, &b, &x); 68 add(a, b, x); 69 add(b, a, x); 70 } 71 scanf("%d%d", &s, &t); 72 spfa(s); 73 } 74 return 0; 75 }
floyd算法:
1 #include <stdio.h> 2 #define INF 0x3f3f3f3f 3 #define N 210 4 int dis[N][N]; 5 int n, m; 6 void init() 7 { 8 for(int i = 0; i < n; i++) 9 for(int j = 0; j < n; j++) 10 if(j == i) 11 dis[i][j] = 0; 12 else 13 dis[i][j] = INF; 14 } 15 void floyd() 16 { 17 for(int k = 0; k < n; k++) 18 for(int i = 0; i < n; i++) 19 { 20 if(dis[i][k] != INF) 21 { 22 for(int j = 0; j < n; j++) 23 if(dis[i][j] > dis[i][k] + dis[k][j]) 24 dis[i][j] = dis[i][k] + dis[k][j]; 25 } 26 } 27 } 28 int main() 29 { 30 int a, b, x; 31 while(~scanf("%d%d", &n, &m)) 32 { 33 init(); 34 while(m--) 35 { 36 scanf("%d%d%d", &a, &b, &x); 37 if(dis[a][b] > x) 38 dis[a][b] = dis[b][a] = x; 39 } 40 floyd(); 41 int s, t; 42 scanf("%d%d", &s, &t); 43 if(dis[s][t] != INF) 44 printf("%d ", dis[s][t]); 45 else 46 printf("-1 "); 47 } 48 return 0; 49 }