Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11
思路:最短路径问题,注意当距离相同的时候要取较小的那个花费
View Code
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<stdlib.h> 5 #include<math.h> 6 #include<algorithm> 7 #define LL long long 8 #define mod 1e9 + 7 9 #define MAX 0x7fffffff 10 const int M = 1005; 11 12 using namespace std; 13 14 int map[M][M], dis[M], vis[M]; 15 int cost[M][M], value[M]; 16 17 int main() 18 { 19 int n, m; 20 int min; 21 int a, b, c, d, temp, s, e; 22 while(scanf("%d%d",&n,&m) , n || m) 23 { 24 for(int i = 1; i <= n; ++i) 25 for(int j = 1; j <= n; ++j) 26 { 27 map[i][j] = MAX; 28 cost[i][j] = MAX; 29 } 30 while(m--) 31 { 32 scanf("%d%d%d%d",&a,&b,&c,&d); 33 if(map[a][b] > c) 34 { 35 map[a][b] = map[b][a] = c; 36 cost[a][b] = cost[b][a] = d; 37 } 38 else if(map[a][b] == c) 39 { 40 if(cost[a][b] > d) 41 cost[a][b] = cost[b][a] = d; 42 } 43 } 44 scanf("%d%d",&s,&e); 45 for(int i = 1; i <= n; ++i) 46 { 47 dis[i] = map[s][i]; 48 value[i] = cost[s][i]; 49 } 50 memset(vis,0,sizeof(vis)); 51 vis[s] = 1; 52 dis[s] = 0; 53 value[s] = 0; 54 for(int i = 1; i < n; ++i) 55 { 56 min = MAX; 57 for(int j = 1; j <= n; ++j) 58 { 59 if(!vis[j] && min > dis[j]) 60 { 61 min = dis[j]; 62 temp = j; 63 } 64 } 65 if(min == MAX) 66 break; 67 vis[temp] = 1; 68 for(int j = 1; j <= n; ++j) 69 { 70 if(!vis[j] && map[temp][j] < MAX) 71 { 72 if(dis[j] > dis[temp] + map[temp][j]) 73 { 74 dis[j] = dis[temp] + map[temp][j]; 75 value[j] = value[temp] + cost[temp][j]; 76 } 77 else if(dis[temp] + map[temp][j] == dis[j]) 78 { 79 if(value[j] > value[temp] + cost[temp][j]) 80 value[j] = value[temp] + cost[temp][j]; 81 } 82 } 83 } 84 } 85 printf("%d %d\n",dis[e],value[e]); 86 } 87 return 0; 88 }
浙公网安备 33010602011771号