比赛 |
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;
}