#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 2E5, MAXSEQ = 2E5, MAXPAIR = 5E5;
vector<int> seq[MAXSEQ+5];
pair<int, int> para[MAXPAIR+5];
struct VERTEX
{
vector<int> pair_num;
vector<int> edge;
int curr_name, p, qt, tree_num;
bool vis;
};
VERTEX fio[MAXN+MAXSEQ+5];
int seq_qt, n, pair_qt;
long long result;
int find(int x)
{
if(fio[x].p!=x) fio[x].p=find(fio[x].p);
return fio[x].p;
}
void union_set(int x, int y)
{
x=find(x);
y=find(y);
if(x>y)
fio[y].p=x;
else
fio[x].p=y;
}
void DFS(int curr, int prev, int tree_num)
{
int partner;
fio[curr].vis=true;
fio[curr].tree_num = tree_num;
for(vector<int>::iterator it = fio[curr].pair_num.begin(); it!=fio[curr].pair_num.end(); ++it)
{
if (para[*it].first == curr)
partner = para[*it].second;
else partner = para[*it].first;
if(fio[partner].vis == true && fio[curr].tree_num == fio[partner].tree_num)
seq[find(partner) - n].push_back(*it);
}
for(vector<int>::iterator it = fio[curr].edge.begin(); it!=fio[curr].edge.end(); ++it)
DFS(*it, curr, tree_num);
union_set(curr, prev);
}
int main()
{
scanf("%d%d%d", &n, &seq_qt, &pair_qt);
for(int i=1; i<=n; ++i)
{
scanf("%d", &(fio[i].qt));
fio[i].p = i;
fio[i].curr_name = i;
}
for(int i=1; i<=seq_qt; ++i)
{
int a, b;
scanf("%d%d", &a, &b);
fio[i+n].edge.push_back(fio[a].curr_name);
fio[i+n].edge.push_back(fio[b].curr_name);
fio[a].curr_name = i+n;
fio[b].curr_name = i+n;
fio[i+n].p = i+n;
}
for(int i=1; i<=pair_qt; i++)
{
int a, b;
scanf("%d%d", &a, &b);
para[i]=make_pair(a, b);
fio[a].pair_num.push_back(i);
fio[b].pair_num.push_back(i);
}
for(int i=seq_qt; i>0; --i)
{
if(!fio[n+i].vis)DFS(n+i, 0, i);
}
for(int i=1; i<=seq_qt; ++i)
{
sort(seq[i].begin(), seq[i].end());
for(vector<int>::iterator it=seq[i].begin(); it!=seq[i].end(); ++it)
{
int mini;
mini = min(fio[para[*it].first].qt, fio[para[*it].second].qt);
fio[para[*it].first].qt -= mini;
fio[para[*it].second].qt -= mini;
result += mini;
}
}
result *= 2LL;
printf("%lld\n", 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 | #include <cstdio> #include <algorithm> #include <vector> using namespace std; const int MAXN = 2E5, MAXSEQ = 2E5, MAXPAIR = 5E5; vector<int> seq[MAXSEQ+5]; pair<int, int> para[MAXPAIR+5]; struct VERTEX { vector<int> pair_num; vector<int> edge; int curr_name, p, qt, tree_num; bool vis; }; VERTEX fio[MAXN+MAXSEQ+5]; int seq_qt, n, pair_qt; long long result; int find(int x) { if(fio[x].p!=x) fio[x].p=find(fio[x].p); return fio[x].p; } void union_set(int x, int y) { x=find(x); y=find(y); if(x>y) fio[y].p=x; else fio[x].p=y; } void DFS(int curr, int prev, int tree_num) { int partner; fio[curr].vis=true; fio[curr].tree_num = tree_num; for(vector<int>::iterator it = fio[curr].pair_num.begin(); it!=fio[curr].pair_num.end(); ++it) { if (para[*it].first == curr) partner = para[*it].second; else partner = para[*it].first; if(fio[partner].vis == true && fio[curr].tree_num == fio[partner].tree_num) seq[find(partner) - n].push_back(*it); } for(vector<int>::iterator it = fio[curr].edge.begin(); it!=fio[curr].edge.end(); ++it) DFS(*it, curr, tree_num); union_set(curr, prev); } int main() { scanf("%d%d%d", &n, &seq_qt, &pair_qt); for(int i=1; i<=n; ++i) { scanf("%d", &(fio[i].qt)); fio[i].p = i; fio[i].curr_name = i; } for(int i=1; i<=seq_qt; ++i) { int a, b; scanf("%d%d", &a, &b); fio[i+n].edge.push_back(fio[a].curr_name); fio[i+n].edge.push_back(fio[b].curr_name); fio[a].curr_name = i+n; fio[b].curr_name = i+n; fio[i+n].p = i+n; } for(int i=1; i<=pair_qt; i++) { int a, b; scanf("%d%d", &a, &b); para[i]=make_pair(a, b); fio[a].pair_num.push_back(i); fio[b].pair_num.push_back(i); } for(int i=seq_qt; i>0; --i) { if(!fio[n+i].vis)DFS(n+i, 0, i); } for(int i=1; i<=seq_qt; ++i) { sort(seq[i].begin(), seq[i].end()); for(vector<int>::iterator it=seq[i].begin(); it!=seq[i].end(); ++it) { int mini; mini = min(fio[para[*it].first].qt, fio[para[*it].second].qt); fio[para[*it].first].qt -= mini; fio[para[*it].second].qt -= mini; result += mini; } } result *= 2LL; printf("%lld\n", result); return 0; } |
English