P5304 [GXOI/GZOI2019]旅行者(最短路/乱搞)
Orz自己想出神仙正解的sxy
描述略
直接把所有起点推进去跑dijkstra...
并且染色,就是记录到这个点的最短路是由哪个起点引导出来的
然后再把所有边反指跑一次...
之后枚举每一条边两边的点不同色就可以更新答案
这个可能少有的代码比说得清楚...
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<queue> 3 #include<algorithm> 4 using std::min; 5 using std::priority_queue; 6 typedef long long lint; 7 const int N=100011,M=1000011; 8 template<typename tp>inline void read(tp &kk) 9 { 10 tp ret=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();} 13 kk=ret*f; 14 } 15 int n,m,k; 16 struct sumireko{int to,ne;lint v;}e[M]; 17 int he[N],ecnt; 18 void addline(int f,int t,lint v) 19 { 20 if(f==t) return; 21 e[++ecnt].to=t; 22 e[ecnt].ne=he[f]; 23 e[ecnt].v=v; 24 he[f]=ecnt; 25 } 26 27 int X[M],Y[M],l[N];lint V[M]; 28 lint d[2][N];int fa[2][N]; 29 struct shino{ 30 lint di;int id; 31 shino(){} 32 shino(int ii,lint dd){id=ii,di=dd;} 33 bool friend operator < (shino a,shino b){return a.di>b.di;} 34 }g; 35 priority_queue<shino>q; 36 bool vv[N]; 37 void dijkstra(lint *dis,int *c) 38 { 39 for(int i=1;i<=n;i++) dis[i]=0x3f3f3f3f3f3f3f3f; 40 for(int i=1;i<=k;i++) dis[l[i]]=0,c[l[i]]=l[i],q.push(shino(l[i],0)); 41 while(!q.empty()) 42 { 43 g=q.top(); 44 q.pop(); 45 int x=g.id; 46 vv[x]=1; 47 for(int i=he[x],t;i;i=e[i].ne) 48 { 49 t=e[i].to; 50 if(vv[t]) continue; 51 if(dis[t]>dis[x]+e[i].v) 52 { 53 dis[t]=dis[x]+e[i].v; 54 c[t]=c[x]; 55 q.push(shino(t,dis[t])); 56 } 57 } 58 } 59 } 60 61 62 void clr(){for(int i=1;i<=n;i++) he[i]=0,vv[i]=0;ecnt=0;} 63 int xi,yi,vi,T; 64 int main() 65 { 66 read(T); 67 while(T--) 68 { 69 read(n),read(m),read(k); 70 for(int i=1;i<=m;i++) read(X[i]),read(Y[i]),read(V[i]),addline(X[i],Y[i],V[i]); 71 for(int i=1;i<=k;i++) read(l[i]); 72 dijkstra(d[0],fa[0]); 73 clr(); 74 for(int i=1;i<=m;i++) addline(Y[i],X[i],V[i]); 75 dijkstra(d[1],fa[1]); 76 lint ans=0x3f3f3f3f3f3f3f3f; 77 for(int i=1;i<=m;i++) 78 { 79 xi=X[i],yi=Y[i],vi=V[i]; 80 if(fa[0][xi]&&fa[1][yi]&&(fa[0][xi]^fa[1][yi])) 81 { 82 ans=min(ans,d[0][xi]+vi+d[1][yi]); 83 } 84 } 85 printf("%lld ",ans); 86 clr(); 87 } 88 return 0; 89 }