1. 程式人生 > >團體程序設計天梯賽-練習集 L2-001 緊急救援 (25 分)

團體程序設計天梯賽-練習集 L2-001 緊急救援 (25 分)

一行 int 其中 能夠 stack cstring [] owb ram

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

輸入格式:

輸入第一行給出4個正整數N、M、S、D,其中N(2N500)是城市的個數,順便假設城市的編號為0 ~ (N1);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 <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <string>
  5 #include <algorithm>
  6
#include <utility> 7 #include <vector> 8 #include <map> 9 #include <queue> 10 #include <stack> 11 #include <cstdlib> 12 #include <cmath> 13 typedef long long ll; 14 #define lowbit(x) (x&(-x)) 15 #define ls l,m,rt<<1 16 #define
rs m+1,r,rt<<1|1 17 using namespace std; 18 #define pi acos(-1) 19 #define P pair<ll,ll> 20 int n,m,s,d; 21 const int N = 1e3+100; 22 int pre[N],f[N][N],val[N],sval[N],dis[N],num[N]; 23 //pre[i]:i前面的點 24 //sval[i]:到i時的所有最短路徑裏可以召集的最多的救援隊數量 25 //dis[i]:s 到i 的最短距離 26 //num[i]:到i的最短路徑有幾條 27 int u,v,w; 28 const int inf = 0x3f3f3f3f; 29 stack<int>se; 30 bool vis[N]; 31 void init() 32 { 33 for(int i =0;i<N;i++) 34 { 35 for(int j=0;j<N;j++) 36 { 37 f[i][j]=(i==j?0:inf); 38 } 39 dis[i] = inf; 40 pre[i]=-1; 41 vis[i] = 0; 42 sval[i]=val[i];//易忘記 43 } 44 } 45 void dijk() 46 { 47 dis[s]=0; 48 num[s]=1;//最重要的。 49 for(int i =0;i<n-1;i++) 50 { 51 int maxx,min_num; 52 maxx=inf; 53 for(int j=0;j<n;j++) 54 { 55 if(!vis[j]){ 56 if(maxx>dis[j]){ 57 maxx=dis[j]; 58 min_num=j; 59 } 60 } 61 } 62 vis[min_num]=1; 63 for(int k=0;k<n;k++){ 64 if(!vis[k]){ 65 66 if(dis[k]>dis[min_num]+f[min_num][k]){ 67 dis[k]=dis[min_num]+f[min_num][k]; 68 sval[k]=sval[min_num]+val[k]; 69 pre[k]=min_num; 70 num[k]=num[min_num]; 71 } 72 else if(dis[k]==dis[min_num]+f[min_num][k]){ 73 num[k]+=num[min_num]; 74 if(sval[k]<sval[min_num]+val[k]){ 75 sval[k]=max(sval[k],sval[min_num]+val[k]); 76 pre[k]=min_num; //這裏要改變前面的點因為最優路徑只有一條 77 } 78 } 79 } 80 } 81 } 82 } 83 int main() 84 { 85 scanf("%d%d%d%d",&n,&m,&s,&d); 86 for(int i =0;i<n;i++) scanf("%d",&val[i]); 87 init();//一定寫在輸入val[]之後 88 for(int i =0;i<m;i++) 89 { 90 scanf("%d%d%d",&u,&v,&w); 91 f[u][v]=f[v][u]=w; 92 } 93 dijk(); 94 printf("%d %d\n",num[d],sval[d]); 95 int i=d; 96 se.push(i); 97 while(pre[i]!=-1){ 98 i=pre[i]; 99 se.push(i); 100 } 101 while(!se.empty()){ 102 int u =se.top(); 103 if(u==d) break; 104 se.pop(); 105 printf("%d ",u); 106 } 107 printf("%d\n",d); 108 return 0; 109 }

團體程序設計天梯賽-練習集 L2-001 緊急救援 (25 分)