1. 程式人生 > >L2-001. 緊急救援(PAT)~最短路應用

L2-001. 緊急救援(PAT)~最短路應用

長度 eof pan sizeof clas ron 全國 color jks

作為一個城市的應急救援隊伍的負責人,你有一張特殊的全國地圖。在地圖上顯示有多個分散的城市和一些連接城市的快速道路。每個城市的救援隊數量和每一條連接兩個城市的快速道路長度都標在地圖上。當其他城市有緊急求助電話給你的時候,你的任務是帶領你的救援隊盡快趕往事發地,同時,一路上召集盡可能多的救援隊。

輸入格式:

輸入第一行給出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

這題是一題最短路變形(寫了這麽多最短路還是不會寫) 我多半是個廢人吧。

通過這題學會了如何記錄路徑,和最短路的條數 ( 感覺自己是個智障)

這題其實就是找到最短路。

找出有多少最短路。

然後在最短裏面找到一個擁有最大救援隊的路,記錄這條路徑。

以前只會找最短路後面的兩個要求都不會。

way[maxn] 這個數組用來記錄那條最優解的路徑

fa[maxn] 還要通過這個數組進行結合才能找到路徑

fa[i] 表示 i 前面的節點

sumteam[maxn] 這個是對應節點的最大救援隊的數目

本題還有一個坑點 輸出首尾不能有多余空格

對應格式卡的特別死

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 const int inf=0x3f3f3f3f;
 7 const int maxn=505
; 8 int n,m,s,d; 9 int tu[maxn][maxn],dis[maxn],vis[maxn],way[maxn]; 10 int team[maxn],sumteam[maxn],sumway[maxn],fa[maxn]; 11 void dijkstra(int s) 12 { 13 memset(dis,0x3f,sizeof(dis)); 14 dis[s]=0; 15 vis[s]=1; 16 sumway[s]=1; 17 sumteam[s]=team[s]; 18 for (int i=0 ;i<n ;i++){ 19 if (tu[s][i]!=inf && i!=s ){ 20 dis[i]=dis[s]+tu[s][i]; 21 fa[i]=s; 22 sumteam[i]=team[i]+sumteam[s]; 23 sumway[i]=1; 24 } 25 } 26 for (int i=0 ;i<n-1 ;i++){ 27 int mind=inf,mint=0,p=s; 28 for (int j=0 ;j<n ;j++ ){ 29 if (!vis[j] && dis[j]<mind) { 30 mind=dis[j]; 31 p=j; 32 } 33 } 34 vis[p]=1; 35 for (int j=0 ;j<n ;j++){ 36 if (!vis[j]) { 37 if (dis[j]>dis[p]+tu[p][j]) { 38 dis[j]=dis[p]+tu[p][j]; 39 sumway[j]=sumway[p]; 40 sumteam[j]=sumteam[p]+team[j]; 41 fa[j]=p; 42 }else if (dis[j]==dis[p]+tu[p][j]) { 43 sumway[j]+=sumway[p]; 44 if (sumteam[j]<sumteam[p]+team[j]){ 45 sumteam[j]=sumteam[p]+team[j]; 46 fa[j]=p; 47 } 48 } 49 } 50 } 51 } 52 } 53 int main() { 54 scanf("%d%d%d%d",&n,&m,&s,&d); 55 for (int i=0 ; i<n ; i++) 56 scanf("%d",&team[i]); 57 memset(tu,inf,sizeof(tu)); 58 int a,b,c; 59 for (int i=0 ; i<m ; i++) { 60 scanf("%d%d%d",&a,&b,&c); 61 tu[a][b]=min(tu[a][b],c); 62 tu[b][a]=tu[a][b]; 63 } 64 dijkstra(s); 65 int num=0,son=d; 66 while(son!=s) { 67 way[num++]=son; 68 son=fa[son]; 69 } 70 way[num++]=s; 71 printf("%d %d\n",sumway[d],sumteam[d]); 72 for (int i=num-1 ; i>0 ; i--) 73 printf("%d ",way[i]); 74 printf("%d\n",way[0]); 75 return 0; 76 }

L2-001. 緊急救援(PAT)~最短路應用