牛客小白月赛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;
}