欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

牛客小白月赛24 E.旅旅旅游(最短路&并查集)

程序员文章站 2022-06-08 19:06:06
...

牛客小白月赛24 E.旅旅旅游(最短路&并查集)

题目传送门

思路:
牛客小白月赛24 E.旅旅旅游(最短路&并查集)

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=5e5+5;
typedef long long ll;
ll d1[N],d2[N];
int n,m,s[N];
struct node{
    ll d;
    int id;
    bool operator<(const node &a)const{
        return d>a.d;
    }
}now; 
vector<node>vi[N];
struct edge{
    int u,v,w;
}e[M];
void dij(int x,ll dis[]){
    for(int i=1;i<=n;i++) dis[i]=1e15;
    dis[x]=0;
    priority_queue<node>q;
    q.push({dis[x],x});
    while(q.size()){
        now=q.top();q.pop();
        if(dis[now.id]<now.d) continue;//代替了vis[i]的作用. 
        int u=now.id;
        for(auto it:vi[u]){
            int v=it.id,w=it.d;
            if(dis[v]>dis[u]+w)
                dis[v]=dis[u]+w,q.push({dis[v],v});
        }
    }
}
int find(int x){
    if(x!=s[x]) s[x]=find(s[x]);
    return s[x];
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1,u,v,w;i<=m;i++){
         scanf("%d%d%d",&u,&v,&w);
         vi[u].push_back({w,v});
         vi[v].push_back({w,u});
         e[i]={u,v,w}; 
    }
    dij(1,d1);
    dij(n,d2);
    ll mn=d1[n];
    int cnt=n;
    for(int i=1;i<=n;i++) s[i]=i;
    for(int i=1;i<=m;i++){
         if(d1[e[i].u]+d2[e[i].v]+e[i].w==mn||d1[e[i].v]+d2[e[i].u]+e[i].w==mn) continue;
         int fa=find(e[i].u),fb=find(e[i].v);
         if(fa!=fb){
            s[fa]=fb;
            cnt--;
         }
    }
    puts(cnt==1?"YES":"NO");
    return 0;
}