我的代码:
#include<bits/stdc++.h>
using namespace std;
const long long INF=1e18;
int n,m,h;
bool can[200001];
vector<pair<int,int> >to[200001];
bool vis[200001][2][2];
long long dis[200001][2][2];
priority_queue<pair<long long,pair<int,bool> >,vector<pair<long long,pair<int,bool> > >,greater<pair<long long,pair<int,bool> > > >q;
void D(int s)//最短路
{
q.push({0,{s,0}});//将起始点推入队列
while(!q.empty())
{
pair<int,bool> u=q.top().second;
u.second|=can[u.first];//如果can[u.first](这个点上有一匹马)为真,在相同的路程下,一定是骑上马更好(能骑上就骑)
if(vis[u.first][u.second][s==n])//[s==n]这一维是标记是以1还是n为起点的最短路
{
q.pop();
continue;
}
dis[u.first][u.second][s==n]=q.top().first;
vis[u.first][u.second][s==n]=true;
int len=to[u.first].size();
for(int i=0;i<len;i++)q.push({dis[u.first][u.second][s==n]+to[u.first][i].second/(u.second+1),{to[u.first][i].first,u.second}});//u.second为真时,时间除以2,可以直接用/(u.second+1)表示
q.pop();
}
return ;
}
int main(){
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&h);
for(int i=1;i<=n;i++)
{
dis[i][0][0]=dis[i][1][0]=dis[i][0][1]=dis[i][1][1]=INF;
vis[i][0][0]=vis[i][1][0]=vis[i][0][1]=vis[i][1][1]=false;
to[i].clear();
can[i]=false;
}
int u,v,w;
for(int i=1;i<=h;i++)
{
scanf("%d",&u);
can[u]=true;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
to[u].push_back({v,w});
to[v].push_back({u,w});
}
D(1);
D(n);
if(min(dis[n][0][0],dis[n][1][0])==INF)printf("-1\n");
else
{
long long ans=INF;
for(int i=1;i<=n;i++)
for(int j=0;j<2;j++)//枚举Robin在会面时是否在马上
for(int k=0;k<2;k++)//枚举Marian在会面时是否在马上
ans=min(ans,max(dis[i][j][0],dis[i][k][1]));
printf("%d\n",ans);
}
}
return 0;
}