#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <set>
using namespace std;
const int N = 200001;
int i, n, t, m, k, a, b;
long long wynik = 0;
int F[N], Z[N], DO[N], P[N];
set <pair<int, int> > REAG;
set<int> MIESZ[N];
set<int>::iterator it;
pair<int,int> KOL[500001];
vector<int> PRIOR[N];
void UNION (int a, int b) {
if(P[a] == a && P[b] == b) { //lacze pojedyncze wierzcholki
if( REAG.find(make_pair(min(a,b),max(a,b))) !=REAG.end()) {
if(F[a] <= F[b]) {
F[b] = F[b] - F[a];
wynik = wynik + 2*F[a];
MIESZ[a].clear();
P[a] = -1;
}
else {
F[a] = F[a] - F[b];
wynik = wynik + 2*F[b];
MIESZ[a].clear();
MIESZ[b].clear();
MIESZ[b].insert(a);
P[b] = -1;
P[a] = -1;
}
}
else {
P[a] = -1;
P[b] = -1;
MIESZ[b].insert(a);
MIESZ[a].clear();
}
}
else if (P[a] == a) {
for(int i = 0; i < PRIOR[a].size(); ++i) if ( MIESZ[b].find(PRIOR[a][i]) != MIESZ[b].end()) {
int f = a, s = PRIOR[a][i];
if(F[f] <= F[s]) {
F[s] = F[s] - F[f];
P[f] = -1;
wynik = wynik + 2*F[f];
MIESZ[a].clear();
}
else {
F[f] = F[f] - F[s];
wynik = wynik + 2*F[s];
MIESZ[b].erase(MIESZ[b].find(s));
P[s] = -1;
}
}
if(F[a] > 0) {
MIESZ[b].insert(a);
P[a] = -1;
MIESZ[a].clear();
}
}
else if(P[b] == b) {
for(int i = 0; i < PRIOR[b].size(); ++i) if ( MIESZ[a].find(PRIOR[b][i]) != MIESZ[a].end()) {
int f = PRIOR[b][i], s = b;
if(F[f] <= F[s]) {
F[s] = F[s] - F[f];
P[f] = -1;
wynik = wynik + 2*F[f];
MIESZ[a].erase(MIESZ[a].find(f));
}
else {
F[f] = F[f] - F[s];
wynik = wynik + 2*F[s];
MIESZ[s].clear();
P[s] = -1;
}
for(it = MIESZ[a].begin(); it!= MIESZ[a].end();++it) {
MIESZ[b].insert(*it);
P[*it]=-1;
}
MIESZ[a].clear();
}
}
else
{ //wierzcholkow w poddrzewie jest wiecej
for(int i = 1; i <= k; ++i) {
int f = KOL[i].first, s = KOL[i].second;
if(MIESZ[a].find(f) !=MIESZ[a].end() && MIESZ[b].find(s) !=MIESZ[b].end()){
if(F[f] <= F[s]) {
F[s] = F[s] - F[f];
P[f] = -1;
wynik = wynik + 2*F[f];
MIESZ[a].erase(MIESZ[a].find(f));
}
else {
F[f] = F[f] - F[s];
wynik = wynik + 2*F[s];
MIESZ[b].erase(MIESZ[b].find(s));
P[s] = -1;
}
}
else if (MIESZ[b].find(f) !=MIESZ[b].end() && MIESZ[a].find(s) !=MIESZ[a].end()){
if(F[f] <= F[s]) {
F[s] = F[s] - F[f];
P[f] = -1;
wynik = wynik + 2*F[f];
MIESZ[b].erase(MIESZ[b].find(f));
}
else {
F[f] = F[f] - F[s];
wynik = wynik + 2*F[s];
MIESZ[a].erase(MIESZ[a].find(s));
P[s] = -1;
}
}
}
for(it = MIESZ[a].begin(); it!= MIESZ[a].end();++it) {
MIESZ[b].insert(*it);
P[*it]=-1;
}
MIESZ[a].clear();
}
}
int main() {
scanf("%d%d%d",&n,&m,&k);
for(i = 1; i <= n; ++i) {
scanf("%d", &F[i]);
MIESZ[i].insert(i);
P[i] = i;
}
for(i = 1; i <= m; ++i) {
scanf("%d%d",&Z[i],&DO[i]);
}
for(i = 1; i <= k; ++i) {
scanf("%d%d",&a,&b);
REAG.insert(make_pair(min(a,b),max(a,b)));
KOL[i].first = a; KOL[i].second = b;
PRIOR[a].push_back(b);
PRIOR[b].push_back(a);
}
for(i = 1; i <= m; ++i){
a = Z[i]; b = DO[i];
UNION(a, b);
}
printf("%lld\n",wynik);
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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | #include <iostream> #include <vector> #include <algorithm> #include <cstdio> #include <set> using namespace std; const int N = 200001; int i, n, t, m, k, a, b; long long wynik = 0; int F[N], Z[N], DO[N], P[N]; set <pair<int, int> > REAG; set<int> MIESZ[N]; set<int>::iterator it; pair<int,int> KOL[500001]; vector<int> PRIOR[N]; void UNION (int a, int b) { if(P[a] == a && P[b] == b) { //lacze pojedyncze wierzcholki if( REAG.find(make_pair(min(a,b),max(a,b))) !=REAG.end()) { if(F[a] <= F[b]) { F[b] = F[b] - F[a]; wynik = wynik + 2*F[a]; MIESZ[a].clear(); P[a] = -1; } else { F[a] = F[a] - F[b]; wynik = wynik + 2*F[b]; MIESZ[a].clear(); MIESZ[b].clear(); MIESZ[b].insert(a); P[b] = -1; P[a] = -1; } } else { P[a] = -1; P[b] = -1; MIESZ[b].insert(a); MIESZ[a].clear(); } } else if (P[a] == a) { for(int i = 0; i < PRIOR[a].size(); ++i) if ( MIESZ[b].find(PRIOR[a][i]) != MIESZ[b].end()) { int f = a, s = PRIOR[a][i]; if(F[f] <= F[s]) { F[s] = F[s] - F[f]; P[f] = -1; wynik = wynik + 2*F[f]; MIESZ[a].clear(); } else { F[f] = F[f] - F[s]; wynik = wynik + 2*F[s]; MIESZ[b].erase(MIESZ[b].find(s)); P[s] = -1; } } if(F[a] > 0) { MIESZ[b].insert(a); P[a] = -1; MIESZ[a].clear(); } } else if(P[b] == b) { for(int i = 0; i < PRIOR[b].size(); ++i) if ( MIESZ[a].find(PRIOR[b][i]) != MIESZ[a].end()) { int f = PRIOR[b][i], s = b; if(F[f] <= F[s]) { F[s] = F[s] - F[f]; P[f] = -1; wynik = wynik + 2*F[f]; MIESZ[a].erase(MIESZ[a].find(f)); } else { F[f] = F[f] - F[s]; wynik = wynik + 2*F[s]; MIESZ[s].clear(); P[s] = -1; } for(it = MIESZ[a].begin(); it!= MIESZ[a].end();++it) { MIESZ[b].insert(*it); P[*it]=-1; } MIESZ[a].clear(); } } else { //wierzcholkow w poddrzewie jest wiecej for(int i = 1; i <= k; ++i) { int f = KOL[i].first, s = KOL[i].second; if(MIESZ[a].find(f) !=MIESZ[a].end() && MIESZ[b].find(s) !=MIESZ[b].end()){ if(F[f] <= F[s]) { F[s] = F[s] - F[f]; P[f] = -1; wynik = wynik + 2*F[f]; MIESZ[a].erase(MIESZ[a].find(f)); } else { F[f] = F[f] - F[s]; wynik = wynik + 2*F[s]; MIESZ[b].erase(MIESZ[b].find(s)); P[s] = -1; } } else if (MIESZ[b].find(f) !=MIESZ[b].end() && MIESZ[a].find(s) !=MIESZ[a].end()){ if(F[f] <= F[s]) { F[s] = F[s] - F[f]; P[f] = -1; wynik = wynik + 2*F[f]; MIESZ[b].erase(MIESZ[b].find(f)); } else { F[f] = F[f] - F[s]; wynik = wynik + 2*F[s]; MIESZ[a].erase(MIESZ[a].find(s)); P[s] = -1; } } } for(it = MIESZ[a].begin(); it!= MIESZ[a].end();++it) { MIESZ[b].insert(*it); P[*it]=-1; } MIESZ[a].clear(); } } int main() { scanf("%d%d%d",&n,&m,&k); for(i = 1; i <= n; ++i) { scanf("%d", &F[i]); MIESZ[i].insert(i); P[i] = i; } for(i = 1; i <= m; ++i) { scanf("%d%d",&Z[i],&DO[i]); } for(i = 1; i <= k; ++i) { scanf("%d%d",&a,&b); REAG.insert(make_pair(min(a,b),max(a,b))); KOL[i].first = a; KOL[i].second = b; PRIOR[a].push_back(b); PRIOR[b].push_back(a); } for(i = 1; i <= m; ++i){ a = Z[i]; b = DO[i]; UNION(a, b); } printf("%lld\n",wynik); return 0; } |
English