按照《算法竞赛进阶指南》写的
哦对了,注意下最后判断,因为开始拓扑的时候,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 "); else printf("%lld ", dis[i]); } return 0; }