PTA_L2題解集
阿新 • • 發佈:2020-10-11
L2-001 緊急救援
題解:因為沒有負邊權,所以我使用的是最優化的優先佇列dijkstra演算法。設num[i]表示到達i點最短路的路徑數量,sum[i]表示到達i點最短路的時候的最大權值和。當d[v]>d[u]+edge[i].w時,更新d[v]值,同時num[v]=num[u] . sum[v]=sum[u]+a[v]。如果d[v]=d[u]+edge[i].w時,需要更新的是num[v]的數量,即num[v]+=num[u],同時可以更新sum的情況,if(sum[v]<sum[u]+a[v])sum[v]=sum[u]+a[v];具體看程式碼
#include<bits/stdc++.h> #pragmaView CodeGCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define white 0 #define grey 1 #define black 2 #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); usingnamespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=3e5+5; int tot,head[maxn]; struct E{ int to,next,w; }edge[maxn<<1]; void add(int u,int v,int w){ edge[tot].to=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot++; }int n,m,S,T; int a[maxn],d[maxn],color[maxn],pre[maxn]; int num[maxn],sum[maxn]; priority_queue<pair<int,int> >q; void dijkstra(int s){ for(int i=1;i<=n;i++) color[i]=white,d[i]=INF,pre[i]=s; q.push({0,s});d[s]=0;color[s]=grey; num[s]=1;sum[s]=a[s];pre[s]=0; while(!q.empty()){ pair<int,int> f=q.top();q.pop(); int u=f.second; color[u]=black; if(d[u]<(-1)*f.first) continue; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(color[v]==black) continue; if(d[v]>d[u]+edge[i].w){ d[v]=d[u]+edge[i].w; pre[v]=u; num[v]=num[u]; sum[v]=sum[u]+a[v]; color[v]=grey; q.push({(-1)*d[v],v}); } else if(d[v]==d[u]+edge[i].w){ num[v]+=num[u]; if(sum[v]<sum[u]+a[v]){ sum[v]=sum[u]+a[v]; pre[v]=u; } } } } } stack<int> s; void get_path(int t){ while(t){ s.push(t-1); t=pre[t]; } } int main(){ scanf("%d%d%d%d",&n,&m,&S,&T);mem(head,-1); ++S;++T; rep(i,1,n) scanf("%d",&a[i]); rep(i,1,m){ int u,v,w;scanf("%d%d%d",&u,&v,&w); ++u;++v; add(u,v,w);add(v,u,w); } dijkstra(S); cout<<num[T]<<" "<<sum[T]<<endl; get_path(T); while(!s.empty()){ int cur=s.top();s.pop(); if(s.size()) cout<<cur<<" "; else cout<<cur; } }