做题记录整理图论/tarjan P5304 [GXOI/GZOI2019]旅行者(2022/10/19)
如果按照出题人的做法那的确是紫题,但是按照题解里的大佬的做法撑死也就是蓝题
https://www.luogu.com.cn/blog/Venus/solution-p5304
#include<bits/stdc++.h>
#define for1(i,a,b) for(int i = a;i<=b;i++)
#define ll long long
#define mp(a,b) make_pair(a,b)
using namespace std;
struct node{
int to,nex,w,id;
}e[1000010];
struct node2{
int u,v,w;
}ed[1000010*2];
int hd[200010],cnt,a[200010],ji[200010][2],n,m,k,vis[200010];
ll dis[200010][2];
void ru(int u,int v,int w)
{
e[++cnt]=(node){v,hd[u],w,0};
hd[u]=cnt;
e[++cnt]=(node){u,hd[v],w,1};
hd[v]=cnt;
}
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >q;
void cl()
{
ll ans=1e18+10;
for1(i,1,n)
dis[i][0]=1e18,vis[i]=0;
for1(i,1,k)
{
dis[a[i]][0]=0;
ji[a[i]][0]=a[i];
q.push(mp(0,a[i]));
}
while(!q.empty())
{
pair<ll,int> now=q.top();
q.pop();
int u=now.second;
if(vis[u]) continue;
vis[u]=1;
for(int i=hd[u];i;i=e[i].nex)
{
if(e[i].id) continue;
int v=e[i].to;
if(dis[v][0]>dis[u][0]+e[i].w)
{
dis[v][0]=dis[u][0]+e[i].w;
q.push(mp(dis[v][0],v));
ji[v][0]=ji[u][0];
}
}
}
for1(i,1,n)
dis[i][1]=1e18,vis[i]=0;
for1(i,1,k)
{
dis[a[i]][1]=0;
ji[a[i]][1]=a[i];
q.push(mp(0,a[i]));
}
while(!q.empty())
{
pair<ll,int> now=q.top();
q.pop();
int u=now.second;
if(vis[u]) continue;
vis[u]=1;
for(int i=hd[u];i;i=e[i].nex)
{
if(!e[i].id) continue;
int v=e[i].to;
if(dis[v][1]>dis[u][1]+e[i].w)
{
dis[v][1]=dis[u][1]+e[i].w;
q.push(mp(dis[v][1],v));
ji[v][1]=ji[u][1];
}
}
}
for1(i,1,m)
{
int u=ed[i].u,v=ed[i].v;
if(ji[u][0]==ji[v][1]) continue;
ans=min(ans,ed[i].w+dis[u][0]+dis[v][1]);
}
printf("%lld\n",ans);
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>m>>k;
int x,y,z;
for1(i,1,m)
{
cin>>x>>y>>z;
ru(x,y,z);
ed[i]=(node2){x,y,z};
}
for1(i,1,k)
cin>>a[i];
cl();
for1(i,1,n)
hd[i]=0;
cnt=1;
}
return 0;
}

浙公网安备 33010602011771号