E. Rendez-vous de Marian et Robin
分层图图论问题:
代码:
#include <bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define all(v) v.begin(),v.end()
using namespace std;
const int inf = 0x3f3f3f3f3f3f3f;
const int N = 4e5+5;
int n,m,k;
struct node{int x,w,id;bool operator<(const node &u)const{return w==u.w?x>u.x:w>u.w;}
};
vector<node>g[N];
int st[N];//horse
int d[N][2],dd[N][2];
int ok[N][2];void dijkstra(){priority_queue<node>pq;for(int i=1;i<=n;i++){d[i][0] = d[i][1] = inf;}pq.push({1LL,d[1][st[1]] = 0,st[1]});while(!pq.empty()){int x = pq.top().x;int w = pq.top().w;int op = pq.top().id;pq.pop();if(ok[x][op])continue;ok[x][op] = 1;for(const auto &[y,ww,opp]:g[x]){if(op){if(d[y][1]>d[x][1]+ww/2LL){d[y][1] = d[x][1] + ww/2LL;pq.push({y,d[y][1],1LL});}}else if(st[y]){if(d[y][1]>d[x][0] + ww){d[y][1] = d[x][0] + ww;pq.push({y,d[y][1],1LL});}}else{if(d[y][0]>d[x][0]+ww){d[y][0] = d[x][0] + ww;pq.push({y,d[y][0],0LL});}}}}return;}void dijkstra1(){priority_queue<node>pq;for(int i=1;i<=n;i++){dd[i][0] = dd[i][1] = inf;}pq.push({n,dd[n][st[n]] = 0,st[n]});while(!pq.empty()){int x = pq.top().x;int w = pq.top().w;int op = pq.top().id;pq.pop();if(ok[x][op])continue;ok[x][op] = 1;for(const auto &[y,ww,opp]:g[x]){if(op){if(dd[y][1]>dd[x][1]+ww/2LL){dd[y][1] = dd[x][1] + ww/2LL;pq.push({y,dd[y][1],1LL});}}else if(st[y]){if(dd[y][1]>dd[x][0] + ww){dd[y][1] = dd[x][0] + ww;pq.push({y,dd[y][1],1LL});}}else{if(dd[y][0]>dd[x][0]+ww){dd[y][0] = dd[x][0] + ww;pq.push({y,dd[y][0],0LL});}}}}return;}void solve(){cin>>n>>m>>k;for(int i=1;i<=n;i++){g[i].clear();st[i] = 0;}for(int i=1;i<=k;i++){int x;cin>>x;st[x] = 1;}for(int i=1;i<=n;i++){ok[i][0] = ok[i][1] = 0;}for(int i=1;i<=m;i++){int x,y,w;cin>>x>>y>>w;g[x].push_back({y,w});g[y].push_back({x,w});}dijkstra();for(int i=1;i<=n;i++){ok[i][0] = ok[i][1] = 0;}dijkstra1();int ans = inf;for(int i=1;i<=n;i++){int res = max(min(d[i][0],d[i][1]),min(dd[i][0],dd[i][1]));ans = min(ans,res);}if(ans>=inf/2LL){cout<<-1<<"\n";return;}else{cout<<ans<<"\n";return;}}signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T = 1;cin>>T;while(T--){solve();}return 0;
}