银川区域赛 H道路与航线(原题啊)

按照《算法竞赛进阶指南》写的

哦对了,注意下最后判断,因为开始拓扑的时候,s可能不在里边,所以不一定等于INF,而是应该大于等于INF

#include<cstring>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#define maxn 50000
using namespace std;
const long long  INF = 1000000000000000;
typedef long long ll;
struct Node {
    int p;
    ll len;
    Node(int a, ll b) :p(a), len(b) {}
};
vector<Node>G[maxn];
vector<int> block[maxn];
 
void insert(int be, int en, ll len) {
    G[be].push_back(Node(en, len));
}
bool operator <(const Node a, const Node b) {
    return a.len > b.len;
}
vector<int>blck[maxn];
queue<int>Q;
priority_queue<Node>que;
int n, m1, m2;
int vis[maxn];
ll dis[maxn];
int clor[maxn];
int de[maxn];
int cnt = 0;
int dfs(int x) {
    vis[x] = 1;
    blck[cnt].push_back(x);
    clor[x] = cnt;
    for (int i = 0; i < G[x].size(); i++) {
        int p = G[x][i].p;
        if (!vis[p]) dfs(p);
    }
    return 0;
}
 
int main() {
    int s;
    scanf("%d %d %d %d", &n, &m1, &m2, &s);
    int be, en;
    ll len;
    for (int i = 0; i < m1; i++) {
        scanf("%d %d %lld", &be, &en, &len);
        insert(be, en, len);
        insert(en, be, len);
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        if (!vis[i]) {
            cnt++;
            dfs(i);
        }
    }
    memset(vis, 0, sizeof(vis));
    for (int i = 0; i < m2; i++) {
        scanf("%d %d %lld", &be, &en, &len);
        insert(be, en, len);
        de[clor[en]]++;
    }
    //dfs2(s);
    for(int i=0;i<=10+n;i++) dis[i] = INF;
    dis[s] = 0;
    for (int i = 1; i <= cnt; i++)  if (!de[i]) Q.push(i);
    Q.push(clor[s]);
 
    while (!Q.empty()) {
        int x = Q.front();  Q.pop();
        for (int j = 0; j < blck[x].size(); j++) {
            int c = blck[x][j];
            que.push(Node(c, dis[c]));
        }
        while (!que.empty()) {
            Node ans = que.top();
            que.pop();
            if (vis[ans.p]) continue;
            vis[ans.p] = 1;
            for (int i = 0; i < G[ans.p].size(); i++) {
                int p = G[ans.p][i].p;
                 
                if (dis[p] > dis[ans.p] + G[ans.p][i].len ) {
                    dis[p] = dis[ans.p] + G[ans.p][i].len;
                    if (clor[p] == clor[ans.p]) que.push(Node(p, dis[p]));
                }
                if (clor[p] != clor[ans.p] && (--de[clor[p]]) == 0) Q.push(clor[p]);
            }
        }
    }
 
    for (int i = 1; i <= n; i++) {
        if (dis[i] > 2000000000) printf("NO PATH\n");
        else printf("%lld\n", dis[i]);
    }
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/lesning/p/11743264.html