旅旅旅遊(最短路、查並集)

在這裏插入圖片描述
在這裏插入圖片描述
解題思路:
在這裏插入圖片描述
代碼:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e6+10;
ll dis1[maxn],dis2[maxn],inf=0x3f3f3f3f3f3f3f3f;
bool vis[maxn];
struct Edge
{
    int u,to,next;
    ll w;
}e[maxn<<1];
int head[maxn],pre[maxn];
int cnt=0,n,m;
struct node
{
    int pos;
    ll d;
    bool operator<(const node& x)const
    {
        return x.d<d;
    }
};
void add(int u,int v,int w)
{
    e[++cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].u=u;
    head[u]=cnt;
}
void dijkstra(int s,ll dis[])
{
    for(int i=1;i<=n;++i) {
        dis[i] = inf;
        vis[i]=false;
    }
    priority_queue<node> q;
    dis[s]=0;
    q.push(node{s,0});
    while(!q.empty())
    {
        node now=q.top();
        q.pop();
        int u=now.pos;
        if(vis[u]) continue;
        vis[u]=true;
        for(int i=head[u];i;i=e[i].next)
        {
            int v=e[i].to;
            if(dis[v]>dis[u]+e[i].w)
            {
                dis[v]=dis[u]+e[i].w;
                if(!vis[v]) q.push(node{v,dis[v]});
            }
        }
    }
}
int find(int x)
{
    if(x==pre[x]) return x;
    return pre[x]=find(pre[x]);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;++i)
    {
        int a,b;
        ll c;
        scanf("%d%d%lld",&a,&b,&c);
        add(a,b,c);
        add(b,a,c);
    }
    dijkstra(1,dis1);
    dijkstra(n,dis2);
    for(int i=1;i<=n;++i)
        pre[i]=i;
    for(int i=1;i<=cnt;i+=2)
    {
        int u=e[i].u;
        int v=e[i].to;
        int w=e[i].w;
        if(dis1[u]+w+dis2[v]==dis1[n]) continue;
        if(dis1[v]+w+dis2[u]==dis1[n]) continue;
        pre[find(u)]=find(v);
    }
    for(int i=1;i<=n;++i)
        find(i);
    int flag=pre[1];
    for(int i=1;i<=n;i++)
        if(pre[i]!=flag)
        {
            puts("NO");
            return 0;
        }
    puts("YES");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章