比赛 4043级NOIP2022欢乐赛6th 评测结果 AATTTTTTTT
题目名称 旅行者 最终得分 20
用户昵称 ZRQ 运行时间 24.880 s
代码语言 C++ 内存使用 14.32 MiB
提交时间 2022-11-18 19:15:29
显示代码纯文本
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=100010,M=500010,INF=0x3f3f3f3f;
struct node
{
	int id;
	ll dis;
	bool operator < (const node &x) const {return dis>x.dis;};
};
int n,m,t,T,id[N],cnt,head[N],nxt[M],e[M],w[M],tot[N];
ll h[N],dis[N],ans=INF;
bool vis[N],done[N];
char ch;
inline void add(int u,int v,int k){nxt[++cnt]=head[u],head[u]=cnt,e[cnt]=v,w[cnt]=k;}
inline void read(int &x){x=0;ch=getchar();while(ch<48||ch>57)ch=getchar();while(ch>47&&ch<58)x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return ;}
bool SPFA(int s)
{
	memset(h,0x3f,sizeof(h));
	queue<int> q;
	q.push(s);
	h[s]=0;
	while(!q.empty())
	{
		int nw=q.front();
		q.pop();
		vis[nw]=0;
		for(int i=head[nw];i;i=nxt[i])
			if(h[e[i]]>h[nw]+w[i])
			{
				h[e[i]]=h[nw]+w[i];
				if(!vis[e[i]])
				{
					++tot[e[i]];
					if(tot[e[i]]==n+1) return 1;
					vis[e[i]]=1;
					q.push(e[i]);
				}
			}
	}
	return 0;
}
void rewrite()
{
	for(int i=1;i<=n;++i)
		for(int j=head[i];j;j=nxt[j])
			w[j]+=h[i]-h[e[j]];
	return ;
}
void Dijkstra(int s)
{
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;++i) dis[i]=INF;
	priority_queue<node> q;
	q.push((node){s,0});
	dis[s]=0;
	while(!q.empty())
	{
		int nw=q.top().id;
		q.pop();
		if(vis[nw]) continue;
		vis[nw]=1;
		for(int i=head[nw];i;i=nxt[i])
			if(dis[e[i]]>dis[nw]+w[i])
			{
				dis[e[i]]=dis[nw]+w[i];
				if(!vis[e[i]]) q.push((node){e[i],dis[e[i]]});
			}
	}
	return ;
}
void Johnson()
{
	for(int i=1;i<=n;++i)
	{
		Dijkstra(i);
		if(done[i])
			for(int j=1;j<=t;++j)
				if(i!=id[j])
					ans=min(ans,dis[id[j]]);
	}
	return ;
} 
int main()
{
	freopen("WAW.in","r",stdin);
	freopen("WAW.out","w",stdout);
	read(T);
	while(T--)
	{
		int u,v,k;
		read(n),read(m),read(t);
		ans=INF;
		for(int i=1;i<=m;++i) read(u),read(v),read(k),add(u,v,k);
		for(int i=1;i<=n;++i) add(n+1,i,0);
		for(int i=1;i<=t;++i) read(id[i]),done[id[i]]=1;
		SPFA(n+1);
		rewrite();
		Johnson();
		printf("%lld\n",ans);
		ans=INF;
		for(int i=1;i<=t;++i) done[id[i]]=0;
		for(int i=1;i<=n+1;++i) head[i]=0;
		for(int i=1;i<=cnt;++i) nxt[i]=0;
	}
	return 0;
 }