旅旅旅遊

題目:旅旅旅遊

題解:分別求出以1爲起點的最短距離,和以n爲起點的最短距離。然後對每條邊進行判斷,判斷這條邊是否爲最短路徑的邊。最後再把剩下的邊判斷一下就好了。

#include <bits/stdc++.h>
#include <cstdlib>
using namespace std;
typedef long long ll;
typedef pair<ll,int>P;
const int N = 5e5+10;
const ll mod = 1e9+7;
const ll inf = 10000000000000000;

int random(int n){
    return (ll)rand()*rand()%n;
}

struct str{
    int v;
    ll s;
    int next;
}e[N<<5];
int head[N<<5],cnt;
int n,m;
map<P,ll>vis;
int vv[N];

void add(int x,int y,ll z){
    e[++cnt].v = y;
    e[cnt].s = z;
    e[cnt].next = head[x];
    head[x] = cnt;
}
void Dijkstra(int s,ll dis[]){
    memset(vv,0,sizeof vv);
    priority_queue<P,vector<P>,greater<P> >que;
    que.push(P(0,s));
    dis[s] = 0;
    while(!que.empty()){
        P t = que.top();
        que.pop();
        if(vv[t.second]) continue;
        vv[t.second] = 1;
        for(int i = head[t.second];i;i = e[i].next){
            int v = e[i].v;
            ll s = e[i].s;
            if(s+t.first < dis[v]){
                dis[v] = s+t.first;
                que.push(P(dis[v],v));
            }
        }
    }
}
ll dis1[N],dis2[N];
int a[N],b[N];
ll c[N];

int Find(int x){
    if(vv[x] == 0) return x;
    else return vv[x] = Find(vv[x]);
}

bool check(){
    int fa = Find(1);
    for(int i = 1;i <= n;i++){
        if(fa != Find(i)) return false;
    }
    return true;
}


int main(){
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= m;i++){
        int x,y;
        ll z;
        scanf("%d%d%lld",&x,&y,&z);
        a[i] = x;b[i] = y;c[i] = z;
        add(x,y,z);
        add(y,x,z);
    }
    for(int i = 1;i <= n;i++){
        dis1[i] = dis2[i] = inf;
    }
    Dijkstra(1,dis1);
    Dijkstra(n,dis2);
    memset(vv,0,sizeof vv);
    for(int i = 1;i <= m;i++){
        int u = a[i],v = b[i];
        if(dis1[u]+dis2[v]+c[i] == dis1[n] || dis1[v]+dis2[u]+c[i] == dis1[n]){
            continue;
        }
        u = Find(u);
        v = Find(v);
        if(u != v){
            if(u > v) swap(u,v);
            vv[u] = v;
        }
    }
    if(check()){
        printf("YES\n");
    }else {
        printf("NO\n");
    }
    return 0;
}
/*
6 9
1 2 1
1 3 1
2 3 3
2 4 1
3 5 4
3 6 3
4 5 1
5 6 1
2 5 2
*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章