#include <cstdio> #include <vector> #include <algorithm> using namespace std; const int LOGN = 19, N = 200001, K = 500000, INF = 1000000; int s[LOGN][N]; int t[LOGN][N]; int in[N]; int out[N]; vector<int> tree[N]; int g[N]; int c[K]; int d[K]; pair<int, int> p[K]; void dfs(int v) { static int time = 0; in[v] = ++time; for(auto u: tree[v]) dfs(u); out[v] = ++time; } bool ancestor(int a, int b) { return in[b] >= in[a] && out[b] <= out[a]; } int time(int a, int b) { if(!ancestor(s[LOGN-1][a], b)) return INF; int ans = 0; for(int i = LOGN - 1; i >= 0; i--) { if(!ancestor(s[i][a], b)) { ans = max(ans, t[i][a]); a = s[i][a]; } if(!ancestor(s[i][b], a)) { ans = max(ans, t[i][b]); b = s[i][b]; } } if(!ancestor(a, b)) ans = max(ans, t[0][a]); if(!ancestor(b, a)) ans = max(ans, t[0][b]); return ans; } int main() { int n, m, k, a, b; long long ans = 0; scanf("%d %d %d", &n, &m, &k); for(int i = 1; i <= n; i++) scanf("%d", g + i); for(int i = 1; i <= m; i++) { scanf("%d %d", &a, &b); tree[b].push_back(a); s[0][a] = b; t[0][a] = i; } for(int i = 1; i <= n; i++) if(s[0][i] == 0) { s[0][i] = i; dfs(i); } for(int i = 1; i < LOGN; i++) for(int j = 1; j <= n; j++) { s[i][j] = s[i-1][s[i-1][j]]; t[i][j] = max(t[i-1][j], t[i-1][s[i-1][j]]); } for(int i = 0; i < k; i++) { scanf("%d %d", c + i, d + i); p[i] = make_pair(time(c[i], d[i]), i); } sort(p, p + k); for(int i = 0; i < k; i++) { if(p[i].first == INF) break; a = c[p[i].second]; b = d[p[i].second]; int z = min(g[a], g[b]); ans += 2 * z; g[a] -= z; g[b] -= z; } printf("%lld\n", ans); }
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 | #include <cstdio> #include <vector> #include <algorithm> using namespace std; const int LOGN = 19, N = 200001, K = 500000, INF = 1000000; int s[LOGN][N]; int t[LOGN][N]; int in[N]; int out[N]; vector<int> tree[N]; int g[N]; int c[K]; int d[K]; pair<int, int> p[K]; void dfs(int v) { static int time = 0; in[v] = ++time; for(auto u: tree[v]) dfs(u); out[v] = ++time; } bool ancestor(int a, int b) { return in[b] >= in[a] && out[b] <= out[a]; } int time(int a, int b) { if(!ancestor(s[LOGN-1][a], b)) return INF; int ans = 0; for(int i = LOGN - 1; i >= 0; i--) { if(!ancestor(s[i][a], b)) { ans = max(ans, t[i][a]); a = s[i][a]; } if(!ancestor(s[i][b], a)) { ans = max(ans, t[i][b]); b = s[i][b]; } } if(!ancestor(a, b)) ans = max(ans, t[0][a]); if(!ancestor(b, a)) ans = max(ans, t[0][b]); return ans; } int main() { int n, m, k, a, b; long long ans = 0; scanf("%d %d %d", &n, &m, &k); for(int i = 1; i <= n; i++) scanf("%d", g + i); for(int i = 1; i <= m; i++) { scanf("%d %d", &a, &b); tree[b].push_back(a); s[0][a] = b; t[0][a] = i; } for(int i = 1; i <= n; i++) if(s[0][i] == 0) { s[0][i] = i; dfs(i); } for(int i = 1; i < LOGN; i++) for(int j = 1; j <= n; j++) { s[i][j] = s[i-1][s[i-1][j]]; t[i][j] = max(t[i-1][j], t[i-1][s[i-1][j]]); } for(int i = 0; i < k; i++) { scanf("%d %d", c + i, d + i); p[i] = make_pair(time(c[i], d[i]), i); } sort(p, p + k); for(int i = 0; i < k; i++) { if(p[i].first == INF) break; a = c[p[i].second]; b = d[p[i].second]; int z = min(g[a], g[b]); ans += 2 * z; g[a] -= z; g[b] -= z; } printf("%lld\n", ans); } |