L2-001. 緊急救援 (Dijkstra算法打印路徑)
阿新 • • 發佈:2018-03-10
長度 printf 一行 span graph scanf 頂點 分開 std
作為一個城市的應急救援隊伍的負責人,你有一張特殊的全國地圖。在地圖上顯示有多個分散的城市和一些連接城市的快速道路。每個城市的救援隊數量和每一條連接兩個城市的快速道路長度都標在地圖上。當其他城市有緊急求助電話給你的時候,你的任務是帶領你的救援隊盡快趕往事發地,同時,一路上召集盡可能多的救援隊。
輸入格式:
輸入第一行給出4個正整數N、M、S、D,其中N(2<=N<=500)是城市的個數,順便假設城市的編號為0~(N-1);M是快速道路的條數;S是出發地的城市編號;D是目的地的城市編號。第二行給出N個正整數,其中第i個數是第i個城市的救援隊的數目,數字間以空格分隔。隨後的M行中,每行給出一條快速道路的信息,分別是:城市1、城市2、快速道路的長度,中間用空格分開,數字均為整數且不超過500。輸入保證救援可行且最優解唯一。
輸出格式:
第一行輸出不同的最短路徑的條數和能夠召集的最多的救援隊數量。第二行輸出從S到D的路徑中經過的城市編號。數字間以空格分隔,輸出首尾不能有多余空格。
輸入樣例:
4 5 0 3 20 30 40 10 0 1 1 1 3 2 0 3 3 0 2 2 2 3 2
輸出樣例:
2 60 0 1 3
1 #include<stdio.h> 2 #include<math.h> 3 #include<stdlib.h> 4 5 #define MAX 502 6 #define INFI 9999999 7 8 int G[MAX][MAX],nv,ne,c1,c2; //圖,結點數,邊數,起點,終點 9 int know[MAX]; //訪問標記 10 int distance[MAX]; //距離 11 int num[MAX]; //最短路徑條數 12 int weight[MAX]; //每個點的權值 13 int w[MAX]; //最短路徑上的點權值總和 14 int pre[MAX]; //存放每個結點前一個結點 15 void printPath( int v); 16 void CreateGraph();17 void Dijkstra( ); 18 int main() 19 { 20 int i; 21 scanf("%d%d%d%d",&nv,&ne,&c1,&c2); 22 for( i=0; i<nv; i++) 23 scanf("%d",&weight[i]); 24 CreateGraph(); 25 Dijkstra(); 26 printf("%d %d\n",num[c2],w[c2]); 27 printPath(c2); 28 return 0; 29 } 30 31 void CreateGraph() 32 { 33 int i,j; 34 int v1,v2; 35 int dn; 36 for( i=0; i<nv; i++) 37 for( j=0; j<nv; j++) 38 G[i][j]=INFI; 39 for( i=0; i<ne; i++) 40 { 41 scanf("%d%d%d",&v1,&v2,&dn); 42 G[v1][v2]=G[v2][v1]=dn; //無向圖 43 } 44 } 45 void Dijkstra( ) 46 { 47 int i,j,k; 48 int min; 49 for( i=0; i<nv; i++) 50 { 51 know[i]=0; 52 distance[i]=G[c1][i]; //更新起點到所有頂點的距離 53 } 54 distance[c1]=0; //起點到起點的距離為0 55 w[c1]=weight[c1]; 56 num[c1]=1; 57 for( i=1; i<nv; i++) 58 { 59 k=-1; 60 min = INFI; 61 for( j=0; j<nv; j++) 62 { 63 if( !know[j] && distance[j]<min) 64 { 65 k=j; 66 min = distance[j]; 67 } 68 } 69 if( k==-1) break; 70 know[k]=1; //尋找到最短的距離,標記該點 71 for( j=0; j<nv; j++) 72 { 73 if( !know[j] && min+G[k][j]<distance[j]) //更新距離 74 { 75 distance[j] = min+G[k][j]; 76 num[j] = num[k]; 77 w[j] = w[k] + weight[j]; 78 pre[j]=k; 79 } 80 else if( !know[j] && min+G[k][j]==distance[j]) 81 { 82 num[j]=num[j]+num[k]; 83 if( w[k]+weight[j]>w[j]) 84 { 85 w[j]=w[k]+weight[j]; 86 pre[j]=k; 87 } 88 } 89 } 90 } 91 } 92 93 void printPath( int v) //遞歸打印路徑 94 { 95 if( v==c1){ 96 printf("%d",v); 97 return; 98 } 99 printPath( pre[v]); 100 printf(" %d",v); 101 }
L2-001. 緊急救援 (Dijkstra算法打印路徑)