#include <cstdio> #include <cassert> #include <algorithm> #include <vector> #include <set> using namespace std; #define MAXN 200010 #define MAXK 500010 int n, m, k; long long together; int g[MAXN], a[MAXN], b[MAXN]; int c[MAXK], d[MAXK]; vector<pair<int,int> > tree[MAXN]; int tree2[MAXN]; int s[MAXN], Time[MAXN], when[MAXN], t=1, sp; vector<pair<int,int> > q[MAXN]; vector<int> reactions[MAXN]; int thisTime; void dfs(int u) { if (!Time[u]) { Time[u] = t++; s[sp] = u; for (vector<pair<int,int> >::iterator it = q[u].begin(); it != q[u].end(); it++) { // działamy tylko wewnątrz tego drzewa if (Time[it->first] < thisTime) continue; if (Time[it->first] > 0) { // binary search na s[0..sp-1] w poszukiwaniu najpóżniejszego o Time <= Time[it->first] int l, r, mid; l = 0; r = sp; while (l+1<r) { mid = (l+r)/2; // r > mid > l if (Time[s[mid]] <= Time[it->first]) { l = mid; } else { r = mid; } } int idx = l; int lca = s[idx]; reactions[when[idx]].push_back(it->second); } } for (vector<pair<int,int> >::iterator it = tree[u].begin(); it != tree[u].end(); it++) { when[sp] = it->second; sp++; dfs(it->first); sp--; } } } int main() { scanf("%d%d%d",&n,&m,&k); for (int i = 1; i <= n; i++) { scanf("%d",&g[i]); } for (int i = 0; i < m; i++) { scanf("%d%d",&a[i],&b[i]); tree[b[i]].push_back(make_pair(a[i],i)); tree2[a[i]] = b[i]; } for (int i = 0; i < k; i++) { scanf("%d%d",&c[i],&d[i]); q[c[i]].push_back(make_pair(d[i], i)); q[d[i]].push_back(make_pair(c[i], i)); } for (int root = 1; root <= n; root++) { if (tree2[root] == 0) { thisTime = t; dfs(root); } } for (int i = 0; i < m; i++) { // reactions[i] wskazuje na indeksy reakcji ktore teraz beda zachodzic // musimy zadbac o kolejnosc zgodna z wejsciem sort(reactions[i].begin(), reactions[i].end()); for (vector<int>::iterator it = reactions[i].begin(); it != reactions[i].end(); it++) { int c1, c2; c1 = c[*it]; c2 = d[*it]; int osad = min(g[c1], g[c2]); g[c1] -= osad; g[c2] -= osad; together += 2 * osad; } } printf("%lld\n", together); }
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 | #include <cstdio> #include <cassert> #include <algorithm> #include <vector> #include <set> using namespace std; #define MAXN 200010 #define MAXK 500010 int n, m, k; long long together; int g[MAXN], a[MAXN], b[MAXN]; int c[MAXK], d[MAXK]; vector<pair<int,int> > tree[MAXN]; int tree2[MAXN]; int s[MAXN], Time[MAXN], when[MAXN], t=1, sp; vector<pair<int,int> > q[MAXN]; vector<int> reactions[MAXN]; int thisTime; void dfs(int u) { if (!Time[u]) { Time[u] = t++; s[sp] = u; for (vector<pair<int,int> >::iterator it = q[u].begin(); it != q[u].end(); it++) { // działamy tylko wewnątrz tego drzewa if (Time[it->first] < thisTime) continue; if (Time[it->first] > 0) { // binary search na s[0..sp-1] w poszukiwaniu najpóżniejszego o Time <= Time[it->first] int l, r, mid; l = 0; r = sp; while (l+1<r) { mid = (l+r)/2; // r > mid > l if (Time[s[mid]] <= Time[it->first]) { l = mid; } else { r = mid; } } int idx = l; int lca = s[idx]; reactions[when[idx]].push_back(it->second); } } for (vector<pair<int,int> >::iterator it = tree[u].begin(); it != tree[u].end(); it++) { when[sp] = it->second; sp++; dfs(it->first); sp--; } } } int main() { scanf("%d%d%d",&n,&m,&k); for (int i = 1; i <= n; i++) { scanf("%d",&g[i]); } for (int i = 0; i < m; i++) { scanf("%d%d",&a[i],&b[i]); tree[b[i]].push_back(make_pair(a[i],i)); tree2[a[i]] = b[i]; } for (int i = 0; i < k; i++) { scanf("%d%d",&c[i],&d[i]); q[c[i]].push_back(make_pair(d[i], i)); q[d[i]].push_back(make_pair(c[i], i)); } for (int root = 1; root <= n; root++) { if (tree2[root] == 0) { thisTime = t; dfs(root); } } for (int i = 0; i < m; i++) { // reactions[i] wskazuje na indeksy reakcji ktore teraz beda zachodzic // musimy zadbac o kolejnosc zgodna z wejsciem sort(reactions[i].begin(), reactions[i].end()); for (vector<int>::iterator it = reactions[i].begin(); it != reactions[i].end(); it++) { int c1, c2; c1 = c[*it]; c2 = d[*it]; int osad = min(g[c1], g[c2]); g[c1] -= osad; g[c2] -= osad; together += 2 * osad; } } printf("%lld\n", together); } |