1. 程式人生 > >L2-001. 緊急救援

L2-001. 緊急救援

min 記錄 using 正整數 目的 ace 多條 救援 連接

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

輸入格式:

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


求最短路徑,最短路徑可能很多條,但是救援隊最多的只有一條,最初用鄰接表+隊列沒做出來,後來用dijkstra算法,多的無非是記錄最短路徑條數,然後每訪問一個點,記住他上一個點,根據條件不斷更新,出現短的路徑要更新,出現救援隊多的也要更新。最後回溯記錄最優解路線。輸出。

代碼:

#include <iostream>
#define
inf 0x3fffffff using namespace std; struct point { int dis,lastp,res,sres,vis,num;//dis 存距離 lastp存路線的上一個點 res存救援隊 sres存累計救援隊 vis標記 num存可行解數目 }p[501];//存點 int length[501][501],path[501],pathnum; int main() { int n,m,s,d,mins=inf,c=0,minres=0; int u,v,w; cin>>n>>m>>s>>d;//
input for(int i=0;i<n;i++) cin>>p[i].res;//input rescue for(int i=0;i<n;i++) { for(int j=0;j<n;j++) length[i][j]=inf; length[i][i]=0; }///initialize for(int i=0;i<m;i++) { cin>>u>>v>>w;//input length[u][v]=length[v][u]=w; } p[s].vis=1,p[s].dis=0,p[s].lastp=-1,p[s].sres=p[s].res; for(int i=0;i<n;i++) { p[i].dis=length[s][i]; if(length[s][i]!=inf&&s!=i)p[i].num=1,p[i].sres=p[i].res+p[s].res;// } ///dijkstra+路徑標記+路徑優化+更新可行路徑條數 for(int i=0;i<n;i++) { int mind=inf,mi; for(int i=0;i<n;i++) { if(p[i].vis==0&&mind>p[i].dis)mind=p[i].dis,mi=i; } p[mi].vis=1; for(int i=0;i<n;i++) { if(p[i].vis==0&&i!=mi)// { if(p[i].dis>p[mi].dis+length[mi][i]) { if(mi==s)p[i].num=1; else p[i].num=p[mi].num;///路徑延伸,條數不變 p[i].dis=p[mi].dis+length[mi][i]; p[i].sres=p[mi].sres+p[i].res; p[i].lastp=mi; } else if(p[i].dis==p[mi].dis+length[mi][i]) { p[i].num+=p[mi].num;///距離相同 此點路徑條數更新 if(p[i].sres<p[mi].sres+p[i].res) { //更新上一個點 p[i].sres=p[mi].sres+p[i].res; p[i].lastp=mi; } } } } } int ans=d;//記錄最優路徑 while(ans!=s) { path[pathnum++]=ans; ans=p[ans].lastp; } path[pathnum++]=ans; cout<<p[d].num<< <<p[d].sres<<endl; for(int i=pathnum-1;i>0;i--) cout<<path[i]<< ; cout<<path[0]; }

L2-001. 緊急救援