#include<cstdio>
#include<cstdlib>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<list>
typedef long long int64;
using namespace std;
typedef struct {
int quan;
vector<pair<int, int> > his;
} sub_t;
typedef struct {
list<int>* subs;
int size;
} fio_t;
typedef struct {
int s1, s2, time, prio;
} rea_t;
bool reas_cmp(const rea_t& r1, const rea_t& r2) {
if (r2.time > r1.time) return true;
if (r2.time < r1.time) return false;
if (r2.prio > r1.prio) return true;
return false;
}
int main () {
int n, m, k, i, from, to, join_from, join_to, tmp, fake_to, li1, li2, last_common, l, ri, mid, amount;
scanf("%d %d %d", &n, &m, &k);
vector<sub_t> subs;
subs.reserve(n + 3);
vector<fio_t> fios;
fios.reserve(n + 3);
list<int>::iterator it;
vector<pair<int, int> >* h1;
vector<pair<int, int> >* h2;
for (i = 0; i < n; ++i) {
sub_t s;
scanf("%d", &s.quan);
s.his.push_back(make_pair(i, -1));
subs.push_back(s);
fio_t f;
f.subs = new list<int>();
f.subs->push_front(i);
f.size = 1;
fios.push_back(f);
}
for (i = 0; i < m; ++i) {
scanf("%d %d", &from, &to);
--from;
--to;
join_from = from;
join_to = to;
if (fios[join_from].size > fios[join_to].size) {
tmp = join_from;
join_from = join_to;
join_to = tmp;
}
fios[to].size += fios[from].size;
fios[from].size = 0;
fake_to = subs[*(fios[join_to].subs->begin())].his[subs[*(fios[join_to].subs->begin())].his.size() - 1].first;
for (it = fios[join_from].subs->begin(); it != fios[join_from].subs->end(); it++) {
subs[*it].his.push_back(make_pair(fake_to, i));
}
fios[join_to].subs->splice(fios[join_to].subs->begin(), *(fios[join_from].subs));
fios[to].subs = fios[join_to].subs;
}
fios.clear();
vector<rea_t> reas;
for (i = 0; i < k; ++i) {
rea_t r;
scanf("%d %d", &r.s1, &r.s2);
--r.s1;
--r.s2;
r.prio = i;
h1 = &(subs[r.s1].his);
h2 = &(subs[r.s2].his);
li1 = h1->size() - 1;
li2 = h2->size() - 1;
if ((*h1)[li1].first != (*h2)[li2].first) {
continue;
}
last_common = -1;
if ((*h1)[li1] == (*h2)[li2]) {
l = 0;
ri = min(li1, li2);
while (ri - l >= 2) {
mid = (ri + l) / 2;
if ((*h1)[li1 - mid] == (*h2)[li2 - mid]) {
l = mid;
continue;
}
ri = mid - 1;
}
last_common = (*h1)[li1 - ri] == (*h2)[li2 - ri] ? ri : l;
}
r.time = max((*h1)[li1 - last_common - 1].second, (*h2)[li2 - last_common - 1].second);
reas.push_back(r);
}
sort(reas.begin(), reas.end(), reas_cmp);
int64 result = 0;
for (i = 0; i < reas.size(); ++i) {
amount = min(subs[reas[i].s1].quan, subs[reas[i].s2].quan);
if (amount == 0) {
continue;
}
subs[reas[i].s1].quan -= amount;
subs[reas[i].s2].quan -= amount;
result += amount;
}
printf("%lld\n", 2 * result);
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 | #include<cstdio> #include<cstdlib> #include<vector> #include<map> #include<set> #include<algorithm> #include<list> typedef long long int64; using namespace std; typedef struct { int quan; vector<pair<int, int> > his; } sub_t; typedef struct { list<int>* subs; int size; } fio_t; typedef struct { int s1, s2, time, prio; } rea_t; bool reas_cmp(const rea_t& r1, const rea_t& r2) { if (r2.time > r1.time) return true; if (r2.time < r1.time) return false; if (r2.prio > r1.prio) return true; return false; } int main () { int n, m, k, i, from, to, join_from, join_to, tmp, fake_to, li1, li2, last_common, l, ri, mid, amount; scanf("%d %d %d", &n, &m, &k); vector<sub_t> subs; subs.reserve(n + 3); vector<fio_t> fios; fios.reserve(n + 3); list<int>::iterator it; vector<pair<int, int> >* h1; vector<pair<int, int> >* h2; for (i = 0; i < n; ++i) { sub_t s; scanf("%d", &s.quan); s.his.push_back(make_pair(i, -1)); subs.push_back(s); fio_t f; f.subs = new list<int>(); f.subs->push_front(i); f.size = 1; fios.push_back(f); } for (i = 0; i < m; ++i) { scanf("%d %d", &from, &to); --from; --to; join_from = from; join_to = to; if (fios[join_from].size > fios[join_to].size) { tmp = join_from; join_from = join_to; join_to = tmp; } fios[to].size += fios[from].size; fios[from].size = 0; fake_to = subs[*(fios[join_to].subs->begin())].his[subs[*(fios[join_to].subs->begin())].his.size() - 1].first; for (it = fios[join_from].subs->begin(); it != fios[join_from].subs->end(); it++) { subs[*it].his.push_back(make_pair(fake_to, i)); } fios[join_to].subs->splice(fios[join_to].subs->begin(), *(fios[join_from].subs)); fios[to].subs = fios[join_to].subs; } fios.clear(); vector<rea_t> reas; for (i = 0; i < k; ++i) { rea_t r; scanf("%d %d", &r.s1, &r.s2); --r.s1; --r.s2; r.prio = i; h1 = &(subs[r.s1].his); h2 = &(subs[r.s2].his); li1 = h1->size() - 1; li2 = h2->size() - 1; if ((*h1)[li1].first != (*h2)[li2].first) { continue; } last_common = -1; if ((*h1)[li1] == (*h2)[li2]) { l = 0; ri = min(li1, li2); while (ri - l >= 2) { mid = (ri + l) / 2; if ((*h1)[li1 - mid] == (*h2)[li2 - mid]) { l = mid; continue; } ri = mid - 1; } last_common = (*h1)[li1 - ri] == (*h2)[li2 - ri] ? ri : l; } r.time = max((*h1)[li1 - last_common - 1].second, (*h2)[li2 - last_common - 1].second); reas.push_back(r); } sort(reas.begin(), reas.end(), reas_cmp); int64 result = 0; for (i = 0; i < reas.size(); ++i) { amount = min(subs[reas[i].s1].quan, subs[reas[i].s2].quan); if (amount == 0) { continue; } subs[reas[i].s1].quan -= amount; subs[reas[i].s2].quan -= amount; result += amount; } printf("%lld\n", 2 * result); return 0; } |
English