團體程序設計天梯賽-練習集
阿新 • • 發佈:2018-07-15
amp style set ring 隊列 初始 can struct val
1 L2-001 緊急救援(25 分) 2 3 #include <iostream> 4 #include <cstdio> 5 #include <algorithm> 6 #include <cstring> 7 #include <vector> 8 #include <utility> 9 #include <queue> 10 using namespace std; 11 typedef pair<int,int>P; 12 int n,m,s,d; 13 const intN=550; 14 const int inf=0x3f3f3f3f; 15 int val[N],dis[N],pre[N],prenum[N]; 16 int tval[N]; 17 struct Node{ 18 int to,w; 19 Node(){} 20 Node(int TO,int W){ 21 to=TO; 22 w=W; 23 } 24 }; 25 vector<Node>vec[N]; 26 void bfs(int sta){ 27 priority_queue<P,vector<P>,greater<P> >que;28 que.push(P(0,sta));//此時的優先隊列會按照first的值排序 29 prenum[sta]=1;//1,不是0 30 tval[sta]=val[sta]; 31 dis[sta]=0; 32 while(!que.empty()){ 33 P q=que.top(); 34 que.pop();//容易忘記,彈出隊列 35 int v=q.second; 36 if(dis[v]<q.first) continue; 37 for(int i=0;i<vec[v].size();i++){38 Node Nod=vec[v][i]; 39 int t=Nod.to; 40 if(dis[t]>dis[v]+Nod.w){ 41 dis[t]=dis[v]+Nod.w; 42 pre[t]=v;//記錄最短路上的該點的前一個點 43 tval[t]=tval[v]+val[t];//救援隊數目是依次累加的 44 prenum[t]=prenum[v]; 45 que.push(P(dis[t],t));//容易忘記,壓入隊列 46 } 47 else if(dis[t]==dis[v]+Nod.w){ 48 prenum[t]+=prenum[v];//到t的路徑數目要加上到v的路徑數目 49 if(tval[t]<tval[v]+val[t]){//只有救援隊數目多了,才會更新節點 50 tval[t]=tval[v]+val[t]; 51 pre[t]=v; 52 } 53 } 54 } 55 } 56 } 57 int main() 58 { 59 scanf("%d%d%d%d",&n,&m,&s,&d); 60 for(int i=0;i<n;i++) 61 scanf("%d",&val[i]); 62 int x,y,z; 63 for(int i=0;i<m;i++){ 64 scanf("%d%d%d",&x,&y,&z); 65 vec[x].push_back(Node(y,z)); 66 vec[y].push_back(Node(x,z));//本題為無向圖 67 } 68 memset(pre,-1,sizeof(pre));//不能初始化為0,0也是節點 69 memset(dis,inf,sizeof(dis)); 70 bfs(s); 71 printf("%d %d\n",prenum[d],tval[d]); 72 int ans=0; 73 int ret[N]; 74 int cur=d; 75 while(cur!=-1){ 76 ret[ans++]=cur; 77 cur=pre[cur]; 78 } 79 for(int i=ans-1;i>=0;i--){ 80 printf("%d%c",ret[i],i==0?‘\n‘:‘ ‘); 81 } 82 return 0; 83 }
團體程序設計天梯賽-練習集