一直想不到建一个点,化成单源最短路。
然后,就变成Dijkstra的水题了。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod=998244353; const int maxn=1e3+50; const int inf=0x3f3f3f3f; struct P{ int to,v; P(){} P(int tto,int vv){to=tto;v=vv;} }; vector<P> p[maxn]; struct up{ bool operator()(const P&p1,const P&p2)const{return p1.v>p2.v;} };//单调递增 //star to (que[].to) cost (que[].v); int vpoi[maxn]; ll dis[maxn],n,maxval; void Dij(int s) { priority_queue<P,vector<P>,up> que; memset(dis,inf,sizeof(dis)); int i,j; int vis[maxn],pre[maxn],k; P poi; for(i=1;i<=n;i++)pre[i]=s,vis[i]=0; for(i=0;i<p[s].size();i++) { dis[p[s][i].to]=p[s][i].v; que.push(P(p[s][i].to,dis[p[s][i].to])); } dis[s]=0;vis[s]=1;pre[s]=0; for(i=1;i<n;i++) { poi=que.top();que.pop(); while(dis[poi.to]!=poi.v||vis[poi.to])//失效或已访问 { poi=que.top();que.pop(); } k=poi.to;vis[k]=1; for(j=0;j<p[k].size();j++) { if(!vis[p[k][j].to]&&dis[p[k][j].to]>dis[k]+p[k][j].v) { dis[p[k][j].to]=dis[k]+p[k][j].v; pre[p[k][j].to]=k; que.push(P(p[k][j].to,dis[p[k][j].to]));//更新 } } } maxval=0; for(i=1;i<=n;i++) { if(maxval<dis[i])maxval=dis[i]; } } int main() { ll T; scanf("%d",&T); while(T--) { int i,j,u,v,w; int V,E,S,K,C,id[maxn][maxn],k[maxn]; memset(id,-1,sizeof(id)); ll ans1,ans2; scanf("%d%d%d%d%d",&V,&E,&S,&K,&C);; for(i=1;i<=V+1;i++)p[i].clear(); for(i=1;i<=K;i++)scanf("%d",&k[i]); for(i=1;i<=E;i++) { scanf("%d%d%d",&u,&v,&w); if(id[u][v]==-1) { id[u][v]=p[u].size();p[u].push_back(P(v,w)); id[v][u]=p[v].size();p[v].push_back(P(u,w)); continue; } if(p[u][id[u][v]].v<=w)continue; p[u][id[u][v]].v=w;p[v][id[v][u]].v=w; } n=V; Dij(S);ans1=maxval; n=V+1; for(i=1;i<=K;i++) { p[V+1].push_back(P(k[i],0)); p[k[i]].push_back(P(V+1,0)); } Dij(V+1);ans2=maxval; // printf("##%lld %lld ",ans1,ans2); if(ans1<=ans2*C)printf("%lld ",ans1); else printf("%lld ",ans2); } }