1. 程式人生 > >hdu-3790 最短路徑問題(雙重權值)

hdu-3790 最短路徑問題(雙重權值)

Problem Description

給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。

 

Input

輸入n,m,點的編號是1~n,然後是m行,每行4個數 a,b,d,p,表示ab之間有一條邊,且其長度為d,花費為p。最後一行是兩個數 s,t;起點s,終點。nm0時輸入結束。
(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 }