#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <unordered_set> #include <unordered_map> using namespace std; #define REP(i,n) for(int i=1; i<=(n); ++i) #define FOR(i,a,b) for(int i=(a); i!=(b); ++i) #define FORE(it,t) for(auto& it: t) typedef vector<int> vi; #define pb push_back typedef pair<int,int> pii; #define st first #define nd second typedef unordered_map<int,int> hii; typedef long long ll; #define INF 1000000001 #define sz size() #define ALL(t) (t).begin(),(t).end() #define SC(a) scanf("%d", &a) #define GET(a) int a; SC(a) #define ISDEBUG 1 #define dprintf(...) if(ISDEBUG) \ {printf("\033[31m"); printf(__VA_ARGS__); printf("\033[0m");} template <class It> void dptab(It b, It e, const char* f="%d ") {if(ISDEBUG) {for(It it=b; it!=e; ++it) dprintf(f, *it); dprintf("\n"); }} #define LH 20 int n, m, k; ll osad; vi amounts; struct node { node* child[2]; vector<pii> reactions; vector<node*> pars; int h; node(node* lchild=0, node* rchild=0) : child{lchild,rchild}, pars(LH), h(0) {} void niszcz() { FORE(ch, child) if(ch) ch->niszcz(); FORE(r, reactions) { ll now = min(amounts[r.st], amounts[r.nd]); osad += 2*now; amounts[r.st] -= now; amounts[r.nd] -= now; } } void dfs(node* par=0) { par = par? par : this; h = par->h+1; pars[0] = par; FOR(i,1,LH) pars[i] = pars[i-1]->pars[i-1]; FORE(ch, child) if(ch) ch->dfs(this); } node* up(int i) { int k = 0; int power = 1; node* n = this; while(i) { if(i&power) { i -= power; n = n->pars[k]; } ++k; power *= 2; } return n; } }; vector<node*> nodes, originals; void build_lca() { FORE(node, nodes) if(node) node->dfs(); } void add_reaction(int aid, int bid) { node *a = originals[aid], *b = originals[bid]; if(a->pars.back() != b->pars.back()) return; if(a->h > b->h) a = a->up(a->h - b->h); if(b->h > a->h) b = b->up(b->h - a->h); for(int i=LH-1; i>=0; --i) { if(a->pars[i] != b->pars[i]) { a = a->pars[i]; b = b->pars[i]; } } a->pars[0]->reactions.pb({aid, bid}); } ll niszcz() { FORE(node, nodes) if(node) node->niszcz(); return osad; } int main() { scanf("%d%d%d", &n, &m, &k); nodes.resize(n+1); amounts.resize(n+1); REP(i,n) { SC(amounts[i]); nodes[i] = new node; } originals = nodes; REP(i,m) { GET(a); GET(b); nodes[b] = new node(nodes[a], nodes[b]); nodes[a] = 0; } build_lca(); REP(i, k) { GET(a); GET(b); add_reaction(a, b); } printf("%lld\n", niszcz()); }
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 | #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <unordered_set> #include <unordered_map> using namespace std; #define REP(i,n) for(int i=1; i<=(n); ++i) #define FOR(i,a,b) for(int i=(a); i!=(b); ++i) #define FORE(it,t) for(auto& it: t) typedef vector<int> vi; #define pb push_back typedef pair<int,int> pii; #define st first #define nd second typedef unordered_map<int,int> hii; typedef long long ll; #define INF 1000000001 #define sz size() #define ALL(t) (t).begin(),(t).end() #define SC(a) scanf("%d", &a) #define GET(a) int a; SC(a) #define ISDEBUG 1 #define dprintf(...) if(ISDEBUG) \ {printf("\033[31m"); printf(__VA_ARGS__); printf("\033[0m");} template <class It> void dptab(It b, It e, const char* f="%d ") {if(ISDEBUG) {for(It it=b; it!=e; ++it) dprintf(f, *it); dprintf("\n"); }} #define LH 20 int n, m, k; ll osad; vi amounts; struct node { node* child[2]; vector<pii> reactions; vector<node*> pars; int h; node(node* lchild=0, node* rchild=0) : child{lchild,rchild}, pars(LH), h(0) {} void niszcz() { FORE(ch, child) if(ch) ch->niszcz(); FORE(r, reactions) { ll now = min(amounts[r.st], amounts[r.nd]); osad += 2*now; amounts[r.st] -= now; amounts[r.nd] -= now; } } void dfs(node* par=0) { par = par? par : this; h = par->h+1; pars[0] = par; FOR(i,1,LH) pars[i] = pars[i-1]->pars[i-1]; FORE(ch, child) if(ch) ch->dfs(this); } node* up(int i) { int k = 0; int power = 1; node* n = this; while(i) { if(i&power) { i -= power; n = n->pars[k]; } ++k; power *= 2; } return n; } }; vector<node*> nodes, originals; void build_lca() { FORE(node, nodes) if(node) node->dfs(); } void add_reaction(int aid, int bid) { node *a = originals[aid], *b = originals[bid]; if(a->pars.back() != b->pars.back()) return; if(a->h > b->h) a = a->up(a->h - b->h); if(b->h > a->h) b = b->up(b->h - a->h); for(int i=LH-1; i>=0; --i) { if(a->pars[i] != b->pars[i]) { a = a->pars[i]; b = b->pars[i]; } } a->pars[0]->reactions.pb({aid, bid}); } ll niszcz() { FORE(node, nodes) if(node) node->niszcz(); return osad; } int main() { scanf("%d%d%d", &n, &m, &k); nodes.resize(n+1); amounts.resize(n+1); REP(i,n) { SC(amounts[i]); nodes[i] = new node; } originals = nodes; REP(i,m) { GET(a); GET(b); nodes[b] = new node(nodes[a], nodes[b]); nodes[a] = 0; } build_lca(); REP(i, k) { GET(a); GET(b); add_reaction(a, b); } printf("%lld\n", niszcz()); } |