Moving Both Hands

Moving Both Hands

//可以选择一个中转点
//也就是先正着走到这个点
//然后再从这个点开始反着走
//但是如果已经开始反着走了,那就只可以反着走图

//正着和反着跑,有点奇妙
//学到了
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf=1e18;
const int M=2e5+5;
using pii=pair<int,int>;

//传的参数太多了,不如写两个
int h1[M],ne1[M],e1[M],w1[M],tot1;
int h2[M],ne2[M],e2[M],w2[M],tot2;

void add1(int from,int to,int wi) {
    e1[++tot1]=to;
    w1[tot1]=wi;
    ne1[tot1]=h1[from];
    h1[from]=tot1;
}

void add2(int from,int to,int wi) {
    e2[++tot2]=to;
    w2[tot2]=wi;
    ne2[tot2]=h2[from];
    h2[from]=tot2;
}

int n,m;
int dis[M][2];
bool vis[M][2];

void dij() {
    for(int i=1;i<=n;i++)
        dis[i][0]=dis[i][1]=inf;
    dis[1][0]=dis[1][1]=0;
    priority_queue<pii,vector<pii>,greater<pii>>q;
    q.push({dis[1][0],1});
    q.push({dis[1][1],-1});
    while(!q.empty()) {
        auto [st,now]=q.top();
        q.pop();
        if(now>0&&vis[now][0]==0) {
            vis[now][0]=1;
            for(int i=h1[now];i;i=ne1[i]) {
                int to=e1[i],wi=w1[i];
                if(dis[to][0]>st+wi) {
                    dis[to][0]=st+wi;
                    q.push({dis[to][0],to});
                }
            }
            for(int i=h2[now];i;i=ne2[i]) {
                int to=e2[i],wi=w2[i];
                if(dis[to][1]>st+wi) {
                    dis[to][1]=st+wi;
                    q.push({dis[to][1],-to});
                }
            }
        }
        if(now<0&&vis[-now][1]==0) {
            now=abs(now);
            vis[now][1]=1;
            for(int i=h2[now];i;i=ne2[i]) {
                int to=e2[i],wi=w2[i];
                if(dis[to][1]>st+wi) {
                    dis[to][1]=st+wi;
                    q.push({dis[to][1],-to});
                }
            }
        }
    }
}
//从某个点开始反水,然后找到那个最小的距离就可以了

signed main() {
    cin>>n>>m;
    while(m--) {
        int u,v,wi;
        cin>>u>>v>>wi;
        add1(u,v,wi);
        add2(v,u,wi);
    }
    dij();
    for(int i=2;i<=n;i++) {
        int ans=min(dis[i][0],dis[i][1]);
        if(ans==inf)cout<<-1<<' ';
        else cout<<ans<<' ';
    }
    return 0;
}
posted @ 2022-11-11 21:16  basicecho  阅读(64)  评论(0)    收藏  举报