E. Rendez-vous de Marian et Robin

发布于:2024-10-12 ⋅ 阅读:(34) ⋅ 点赞:(0)

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


网站公告

今日签到

点亮在社区的每一天
去签到