P5304 [GXOI/GZOI2019]旅行者(最短路/乱搞)

时间:2023-03-09 00:03:16
P5304 [GXOI/GZOI2019]旅行者(最短路/乱搞)

luogu

bzoj

Orz自己想出神仙正解的sxy

描述略

直接把所有起点推进去跑dijkstra...

并且染色,就是记录到这个点的最短路是由哪个起点引导出来的

然后再把所有边反指跑一次...

之后枚举每一条边两边的点不同色就可以更新答案

这个可能少有的代码比说得清楚...

 #include<cstdio>
 #include<queue>
 #include<algorithm>
 using std::min;
 using std::priority_queue;
 typedef long long lint;
 ,M=;
 template<typename tp>inline void read(tp &kk)
 {
     tp ret=,f=;char ch=getchar();
     ;ch=getchar();}
     +ch-';ch=getchar();}
     kk=ret*f;
 }
 int n,m,k;
 struct sumireko{int to,ne;lint v;}e[M];
 int he[N],ecnt;
 void addline(int f,int t,lint v)
 {
     if(f==t) return;
     e[++ecnt].to=t;
     e[ecnt].ne=he[f];
     e[ecnt].v=v;
     he[f]=ecnt;
 }

 int X[M],Y[M],l[N];lint V[M];
 lint d[][N];][N];
 struct shino{
     lint di;int id;
     shino(){}
     shino(int ii,lint dd){id=ii,di=dd;}
     bool friend operator < (shino a,shino b){return a.di>b.di;}
 }g;
 priority_queue<shino>q;
 bool vv[N];
 void dijkstra(lint *dis,int *c)
 {
     ;i<=n;i++) dis[i]=0x3f3f3f3f3f3f3f3f;
     ;i<=k;i++) dis[l[i]]=,c[l[i]]=l[i],q.push(shino(l[i],));
     while(!q.empty())
     {
         g=q.top();
         q.pop();
         int x=g.id;
         vv[x]=;
         for(int i=he[x],t;i;i=e[i].ne)
         {
             t=e[i].to;
             if(vv[t]) continue;
             if(dis[t]>dis[x]+e[i].v)
             {
                 dis[t]=dis[x]+e[i].v;
                 c[t]=c[x];
                 q.push(shino(t,dis[t]));
             }
         }
     }
 }

 ;i<=n;i++) he[i]=,vv[i]=;ecnt=;}
 int xi,yi,vi,T;
 int main()
 {
     read(T);
     while(T--)
     {
         read(n),read(m),read(k);
         ;i<=m;i++) read(X[i]),read(Y[i]),read(V[i]),addline(X[i],Y[i],V[i]);
         ;i<=k;i++) read(l[i]);
         dijkstra(d[],fa[]);
         clr();
         ;i<=m;i++) addline(Y[i],X[i],V[i]);
         dijkstra(d[],fa[]);
         lint ans=0x3f3f3f3f3f3f3f3f;
         ;i<=m;i++)
         {
             xi=X[i],yi=Y[i],vi=V[i];
             ][xi]&&fa[][yi]&&(fa[][xi]^fa[][yi]))
             {
                 ans=min(ans,d[][xi]+vi+d[][yi]);
             }
         }
         printf("%lld\n",ans);
         clr();
     }
     ;
 }

哭唧唧