L2-001 緊急救援 (25分)
阿新 • • 發佈:2020-11-27
與一般最短路題目相比,多了節點的權重以及輸出路徑。
在簡單的djs基礎上,多了到達每個節點的最大救援數以及更新路徑:倒序更新,使用pre函式,如在pre[s(終點)]可能的值中找到最大救援的路徑,這樣就不僅滿足>關係更新,=時也要更新。
inline void djs() { for(re int i=1;i<=n;i++)dis[i]=2147483647; dis[s]=0; priority_queue<node>Q;//初始化 node a ={s,0}; Q.push(a);//第一個node while(!Q.empty()) { node fr=Q.top();Q.pop(); int u=fr.u,d=fr.d; //取出並記錄 if(d!=dis[u])continue;//避免處理無用資料,也就是dis[u]已經更新,之前未更新資料直接出棧,比如有一組資料 2 5,但是後面又入棧一組資料2 3,則2 5是無用資料 for(re int j=0;j<g[u].size();j++) { int tm=g[u][j].to; if(dis[u]+g[u][j].cost<dis[tm]) { dis[tm]=dis[u]+g[u][j].cost; Q.push((node){tm,dis[tm]}); } } } }
#include<bits/stdc++.h> #define intn long long #define ls(k) (k)<<1 #define inf 2147483647 #define re register #define rs(k) (k)<<1|1 #define _0for(i, a) for(int i = 0; i < (a); ++i) #define _1for(i, a) for(int i = 1; i <=(a); ++i) #define lowbit(x) ((x)&(-x)) #define debug(x) \ (void)(cerr << "L" << __LINE__\ << " : " << #x << " = " \ << (x) << endl ) using namespace std; inline int read() { char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } struct edge { int to,cost; }; struct node { int u,d; bool operator <(const node&rhs)const { return d>rhs.d; } }; int n,dis[20000],s,m,d; vector<edge>g[50000]; int road[20000]; int jy[200000]; int pre[200000]; int gejy[200000]; void djs() { for(re int i=0;i<=n;i++)dis[i]=inf; dis[s]=0; priority_queue<node>Q; node a={s,0}; Q.push(a); while(!Q.empty()) { node fr=Q.top(); Q.pop(); int u=fr.u,d=fr.d; if(road[u]==0)road[u]=1; if(d!=dis[u])continue; for(re int j=0;j<g[u].size();j++) { int tm=g[u][j].to; if(dis[u]+g[u][j].cost<dis[tm]) { dis[tm]=dis[u]+g[u][j].cost; Q.push((node){tm,dis[tm]}); road[tm]=road[u]; pre[tm]=u; gejy[tm]=gejy[u]+jy[tm]; } else if(dis[u]+g[u][j].cost==dis[tm]) { road[tm]+=road[u]; if(gejy[tm]<gejy[u]+jy[tm])//找到最大救援數的節點。 { pre[tm]=u; } gejy[tm]=max(gejy[tm],gejy[u]+jy[tm]); } } } } void outpath() { stack<int> st; st.push(d); for(int i=pre[d];i!=-1;i=pre[i]) { st.push(i); } int x=st.top(); printf("%d",x); st.pop(); while(!st.empty()) { int x=st.top(); printf(" %d",x); st.pop(); } } main(void) { cin>>n>>m>>s>>d; fill(pre,pre+10000,-1); for(int i=0;i<n;i++) { cin>>jy[i]; gejy[i]=jy[i]; } for(int i=0;i<m;i++) { int a,b,c; cin>>a>>b>>c; g[a].push_back(edge{b,c}); g[b].push_back(edge{a,c}); } djs(); printf("%d %d\n",road[d],gejy[d]); outpath(); }