// 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; } |