// PA2014, runda 5, Fiolki
// Andrzej Pezarski
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
using namespace std;
int N, M, K, T, T0, TL, L;
long long R;
struct Fiolka {
int p;
int g;
int t;
int t0;
vector<int> ch;
vector<int> X;
};
vector<Fiolka> fiolki;
vector<pair<int, int> > reakcje;
vector<pair<int, int> > LCA;
void zliczLCA(int v, int d) {
fiolki[v].t0=T0;
fiolki[v].t=TL;
LCA[TL++]=make_pair(d, v);
for (auto w:fiolki[v].ch) {
zliczLCA(w, d+1);
LCA[TL++]=make_pair(d, v);
}
}
int lca(int a, int b) {
if (fiolki[a].t0!=fiolki[b].t0) return -1;
a=fiolki[a].t;
b=fiolki[b].t;
if (a>b) swap(a, b);
auto res=min(LCA[a], LCA[b]);
while (a/2!=b/2) {
if (!(a%2)) res=min(res, LCA[a+1]);
if (b%2) res=min(res, LCA[b-1]);
a/=2;
b/=2;
}
return res.second;
}
void GO(int v) {
for (auto k:fiolki[v].X) {
int x=lca(reakcje[k].first, reakcje[k].second);
fiolki[x].X.push_back(k);
}
for (auto w:fiolki[v].ch) {
fiolki[v].X.clear();
GO(w);
sort(fiolki[v].X.begin(), fiolki[v].X.end());
for (auto k:fiolki[v].X) {
int a=reakcje[k].first;
int b=reakcje[k].second;
int g=min(fiolki[a].g, fiolki[b].g);
fiolki[a].g-=g;
fiolki[b].g-=g;
R+=2*g;
}
}
}
int main() {
scanf("%d%d%d", &N, &M, &K);
L=1; while(L<=N) L*=2; L*=2;
fiolki.resize(N);
reakcje.resize(K);
LCA.resize(2*L);
for (auto &f:fiolki) {
scanf("%d", &f.g);
f.p=-1;
}
for (int i=0; i<M; i++) {
int a, b;
scanf("%d%d", &a, &b);
fiolki[a-1].p=b-1;
fiolki[b-1].ch.push_back(a-1);
}
for (auto &r:reakcje) {
scanf("%d%d", &r.first, &r.second);
r.first--, r.second--;
}
// LCA
T=0;
TL=L;
for (int i=0; i<N; i++) {
T0=i;
if (fiolki[i].p==-1) zliczLCA(i, 0);
}
for (int i=L-1; i>0; i--) {
LCA[i]=min(LCA[2*i], LCA[2*i+1]);
}
// rekacje
for (int k=0; k<K; k++) {
int a=reakcje[k].first;
int b=reakcje[k].second;
if (fiolki[a].t0!=fiolki[b].t0) continue;
int x=( (fiolki[a].t>fiolki[b].t)?a:b );
fiolki[x].X.push_back(k);
}
// GO
R=0;
for (int i=0; i<N; i++) {
if (fiolki[i].p==-1) GO(i);
}
printf("%lld\n", R);
return 0;
}
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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | // PA2014, runda 5, Fiolki // Andrzej Pezarski #include <cstdio> #include <cstdlib> #include <vector> #include <set> #include <map> #include <algorithm> using namespace std; int N, M, K, T, T0, TL, L; long long R; struct Fiolka { int p; int g; int t; int t0; vector<int> ch; vector<int> X; }; vector<Fiolka> fiolki; vector<pair<int, int> > reakcje; vector<pair<int, int> > LCA; void zliczLCA(int v, int d) { fiolki[v].t0=T0; fiolki[v].t=TL; LCA[TL++]=make_pair(d, v); for (auto w:fiolki[v].ch) { zliczLCA(w, d+1); LCA[TL++]=make_pair(d, v); } } int lca(int a, int b) { if (fiolki[a].t0!=fiolki[b].t0) return -1; a=fiolki[a].t; b=fiolki[b].t; if (a>b) swap(a, b); auto res=min(LCA[a], LCA[b]); while (a/2!=b/2) { if (!(a%2)) res=min(res, LCA[a+1]); if (b%2) res=min(res, LCA[b-1]); a/=2; b/=2; } return res.second; } void GO(int v) { for (auto k:fiolki[v].X) { int x=lca(reakcje[k].first, reakcje[k].second); fiolki[x].X.push_back(k); } for (auto w:fiolki[v].ch) { fiolki[v].X.clear(); GO(w); sort(fiolki[v].X.begin(), fiolki[v].X.end()); for (auto k:fiolki[v].X) { int a=reakcje[k].first; int b=reakcje[k].second; int g=min(fiolki[a].g, fiolki[b].g); fiolki[a].g-=g; fiolki[b].g-=g; R+=2*g; } } } int main() { scanf("%d%d%d", &N, &M, &K); L=1; while(L<=N) L*=2; L*=2; fiolki.resize(N); reakcje.resize(K); LCA.resize(2*L); for (auto &f:fiolki) { scanf("%d", &f.g); f.p=-1; } for (int i=0; i<M; i++) { int a, b; scanf("%d%d", &a, &b); fiolki[a-1].p=b-1; fiolki[b-1].ch.push_back(a-1); } for (auto &r:reakcje) { scanf("%d%d", &r.first, &r.second); r.first--, r.second--; } // LCA T=0; TL=L; for (int i=0; i<N; i++) { T0=i; if (fiolki[i].p==-1) zliczLCA(i, 0); } for (int i=L-1; i>0; i--) { LCA[i]=min(LCA[2*i], LCA[2*i+1]); } // rekacje for (int k=0; k<K; k++) { int a=reakcje[k].first; int b=reakcje[k].second; if (fiolki[a].t0!=fiolki[b].t0) continue; int x=( (fiolki[a].t>fiolki[b].t)?a:b ); fiolki[x].X.push_back(k); } // GO R=0; for (int i=0; i<N; i++) { if (fiolki[i].p==-1) GO(i); } printf("%lld\n", R); return 0; } |
English