1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| #include <bits/stdc++.h> using namespace std; const int maxn = 3e4 + 50, maxm = 1e5 + 50; int n, m, p, st, tot = -1, head[maxn], d[maxn];
int block[maxn], cnt, ind[maxn];
vector<int> arr[maxn];
queue<int> q1;
struct node { int v_, w_, nxt_, flag_; } g[maxm << 1];
void add(int u, int v, int w, int flag) { g[++tot].v_ = v, g[tot].w_ = w, g[tot].flag_ = flag, g[tot].nxt_ = head[u], head[u] = tot; }
void dfs(int u, int k) { block[u] = k, arr[k].push_back(u); for (int i = head[u]; ~i; i = g[i].nxt_) { int v = g[i].v_, w = g[i].w_, flag = g[i].flag_; if (block[v] || flag) continue; dfs(v, k); } }
void init() { int u, v, w; memset(head, -1, sizeof(head)), memset(d, 0x3f, sizeof(d)); for (int i = 1; i <= m; ++i) { cin >> u >> v >> w; add(u, v, w, 0), add(v, u, w, 0); } for (int i = 1; i <= p; ++i) { cin >> u >> v >> w; add(u, v, w, 1); } }
void dijkstra(int k) { priority_queue<pair<int, int>> q2; bool vis[maxn]; memset(vis, 0, sizeof(vis)); for (auto u : arr[k]) { q2.push({-d[u], u}); } while (!q2.empty()) { int u = q2.top().second; q2.pop(); if (vis[u]) continue; vis[u] = 1; for (int i = head[u]; ~i; i = g[i].nxt_) { int v = g[i].v_, w = g[i].w_, flag = g[i].flag_; if (flag) { d[v] = min(d[v], d[u] + w); if (--ind[block[v]] == 0) q1.push(block[v]); } else { if (d[v] > d[u] + w) { d[v] = d[u] + w; q2.push({-d[v], v}); } } } } }
void toposort() { for (int i = 1; i <= cnt; ++i) { for (auto u : arr[i]) { for (int j = head[u]; ~j; j = g[j].nxt_) { int v = g[j].v_, flag = g[j].flag_; if (flag) ++ind[block[v]]; } } } for (int i = 1; i <= cnt; ++i) { if (!ind[i]) q1.push(i); } d[st] = 0; while (!q1.empty()) { int k = q1.front(); q1.pop(); dijkstra(k); } }
int main() { cin >> n >> m >> p >> st; init(); for (int i = 1; i <= n; ++i) { if (!block[i]) { dfs(i, ++cnt); } } toposort(); for (int i = 1; i <= n; ++i) { if (d[i] > n * 10000) cout << "NO PATH" << endl; else cout << d[i] << endl; } return 0; }
|