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