#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); } |
English