hdu-3790 最短路径问题(双重权值)
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)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2 1 2 5 6 2 3 4 5 1 3 0 0
Sample Output
9 11
再加一组测试数据:
Sample Input:
5 7
1 2 5 5
2 3 4 5
1 3 4 6
3 4 2 2
3 5 4 7
4 5 2 4
1 3 4 4
1 5
Sample Output
8 10
1 #include <stdio.h> 2 #include <string.h> 3 4 #define MAX 1005 5 #define INF 200000000 6 7 struct Route //路线结构体(包括距离和花费) 8 { 9 int dis; 10 int fare; 11 }; 12 13 void dijkstra(struct Route map[][MAX],int dist[],int value[],int start,int end) 14 { 15 int s[MAX]; //集合,用于存放已找出的顶点 16 int u; 17 int minDis; 18 int minVal; 19 int i,j; 20 memset(s,0,sizeof(s)); 21 s[start] = 1; //将起点放入集合 22 for (i=1; i<MAX; i++) 23 { 24 //初始化dist和value 25 dist[i] = map[start][i].dis; 26 value[i] = map[start][i].fare; 27 } 28 //将起点的dist和value置为0 29 dist[start] = 0; 30 value[start] = 0; 31 while (1) 32 { 33 u = start; 34 minDis = INF; 35 minVal = INF; 36 for (i=1; i<MAX; i++) 37 { 38 if (dist[i]<minDis&&!s[i]) //找出距起点最近的点 39 { 40 minVal = value[i]; 41 minDis = dist[i]; 42 u = i; 43 } 44 else if (dist[i]==minDis&&!s[i]&&value[i]<minVal) //如果距离相等,则选择花费最少的 45 { 46 minVal = value[i]; 47 minDis = dist[i]; 48 u = i; 49 } 50 } 51 s[u] = 1; 52 if (s[end]==1) //当找出终点就结束 53 return; 54 for (i=1; i<MAX; i++) //利用找出的点更新其它点到起点的距离和花费 55 { 56 if (!s[i]&&dist[i]>map[u][i].dis+dist[u]) 57 { 58 dist[i] = map[u][i].dis+dist[u]; 59 value[i] = map[u][i].fare+value[u]; 60 } 61 else if (!s[i]&&dist[i]==map[u][i].dis+dist[u]) //如果距离相等,则选择花费最少的 62 if (value[i] > map[u][i].fare+value[u]) 63 { 64 dist[i] = map[u][i].dis+dist[u]; 65 value[i] = map[u][i].fare+value[u]; 66 } 67 } 68 } 69 } 70 71 int main() 72 { 73 struct Route map[MAX][MAX]; //地图的邻接矩阵 74 int dist[MAX]; //存放起点到各点的距离 75 int value[MAX]; //存放起点到各点的花费 76 //int pre[MAX]; 77 int n,m; //n个点,m条边 78 int a,b,d,p; 79 int s,t; //起点,终点 80 int i,j; 81 while (1) 82 { 83 scanf("%d%d",&n,&m); 84 if (n==0&&m==0) 85 break; 86 for (i=1; i<=n; i++) 87 for (j=1; j<MAX; j++) 88 { 89 map[i][j].dis = INF; 90 map[i][j].fare = INF; 91 } 92 for (i=1; i<MAX; i++) 93 { 94 dist[i] = INF; 95 value[i] = INF; 96 } 97 for (i=1; i<=m; i++) //将邻接矩阵初始化 98 { 99 scanf("%d%d%d%d",&a,&b,&d,&p); 100 if (d < map[a][b].dis) 101 { 102 //如果两点间有重边,则选出最短距离 103 map[a][b].dis = map[b][a].dis = d; 104 map[a][b].fare = map[b][a].fare = p; 105 } 106 else if (d == map[a][b].dis&&p < map[a][b].fare) 107 { 108 //重边距离相等,则选出花费最少的 109 map[a][b].dis = map[b][a].dis = d; 110 map[a][b].fare = map[b][a].fare = p; 111 } 112 } 113 scanf("%d%d",&s,&t); 114 dijkstra(map,dist,value,s,t); 115 printf("%d %d\n",dist[t],value[t]); 116 } 117 return 0; 118 }
蒹葭苍苍,白露为霜;
所谓伊人,在水一方。