#include "stdio.h"
#include <set>
#include <queue>
using namespace std;
const int N=200001;
//const int M=500001;
struct reaction {
int other, prior, me;
reaction() : other(0), prior(0), me(0) {}
reaction(int x, int y, int z) : other(x), prior(y), me(z) {}
bool operator < (reaction r) const {
return make_pair(other, prior) < make_pair(r.other, r.prior);
}
};
set< reaction > fiolki[N];
int cap[N];
pair< int,int > steps[N];
set< reaction >::iterator begins[N];
bool q[N];
int react(int s1, int s2) {
if(cap[s1] > cap[s2]) swap(s1,s2);
int result = cap[s1];
cap[s2]-=cap[s1];
cap[s1]=0;
return 2*result;
}
int main()
{
int n,m,k; long long osad=0;
scanf("%d%d%d",&n,&m,&k);
for(int i = 1; i <= n; i++) scanf("%d", &cap[i]);
for(int i = 0; i < m; i++) scanf("%d%d", &steps[i].first, &steps[i].second);
int c,d;
for(int i = 0; i < k; i++) {
scanf("%d%d", &c, &d);
fiolki[c].insert(reaction(d,i,c));
fiolki[d].insert(reaction(c,i,d));
}
fill(q,q+N,false);
for(int i = 0; i < m; i++) {
int a = steps[i].first; int b = steps[i].second;
if(fiolki[a].size() > fiolki[b].size()) swap(fiolki[a],fiolki[b]);
// fprintf(stderr,"fiolka %d wpada do fiolki %d\n",a,b);
priority_queue< pair< int,int > > temp;
fiolki[b].insert( reaction(N,0,0) ); // straznik
for (reaction r : fiolki[a]) {
if(q[r.me]) continue;
q[r.me]=true;
auto it = fiolki[b].lower_bound( reaction(r.me,0,0) );
if( it->other == r.me ) {
// fprintf(stderr,"substancja %d z %d\n",r.me,it->me);
temp.push( make_pair(-(it->prior), r.me) );
//else temp.insert( make_pair(M, r.me) ); // z tymi nikt nie chce zareagowac
begins[r.me]=it;
// fprintf(stderr,"zakolejkowalem %d z prior. %d\n",r.me,it->prior);
}
}
for (reaction r : fiolki[a]) q[r.me]=false;
// w tej petli przeprowadzamy reakcje
while(!temp.empty()) {
int substance1=temp.top().second;
// fprintf(stderr,"priorytet %d\n",-temp.top().first);
temp.pop();
if(cap[substance1]==0) continue;
// wpp pierwsza substancja moze zareagowac
int substance2=begins[substance1]->me;
// fprintf(stderr,"mam substancje %d o pojemnosci %d\n",substance2,cap[substance2]);
if( cap[substance2] != 0 ) {
// fprintf(stderr,"mietolimy %d z %d\n",substance1,substance2);
osad+=react(substance1,substance2);
}
begins[substance1]++;
if( begins[substance1]->other==substance1 )
temp.push( make_pair(-(begins[substance1]->prior), substance1) );
}
fiolki[b].insert( fiolki[a].begin(),fiolki[a].end() );
}
printf("%lld\n", osad);
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 | #include "stdio.h" #include <set> #include <queue> using namespace std; const int N=200001; //const int M=500001; struct reaction { int other, prior, me; reaction() : other(0), prior(0), me(0) {} reaction(int x, int y, int z) : other(x), prior(y), me(z) {} bool operator < (reaction r) const { return make_pair(other, prior) < make_pair(r.other, r.prior); } }; set< reaction > fiolki[N]; int cap[N]; pair< int,int > steps[N]; set< reaction >::iterator begins[N]; bool q[N]; int react(int s1, int s2) { if(cap[s1] > cap[s2]) swap(s1,s2); int result = cap[s1]; cap[s2]-=cap[s1]; cap[s1]=0; return 2*result; } int main() { int n,m,k; long long osad=0; scanf("%d%d%d",&n,&m,&k); for(int i = 1; i <= n; i++) scanf("%d", &cap[i]); for(int i = 0; i < m; i++) scanf("%d%d", &steps[i].first, &steps[i].second); int c,d; for(int i = 0; i < k; i++) { scanf("%d%d", &c, &d); fiolki[c].insert(reaction(d,i,c)); fiolki[d].insert(reaction(c,i,d)); } fill(q,q+N,false); for(int i = 0; i < m; i++) { int a = steps[i].first; int b = steps[i].second; if(fiolki[a].size() > fiolki[b].size()) swap(fiolki[a],fiolki[b]); // fprintf(stderr,"fiolka %d wpada do fiolki %d\n",a,b); priority_queue< pair< int,int > > temp; fiolki[b].insert( reaction(N,0,0) ); // straznik for (reaction r : fiolki[a]) { if(q[r.me]) continue; q[r.me]=true; auto it = fiolki[b].lower_bound( reaction(r.me,0,0) ); if( it->other == r.me ) { // fprintf(stderr,"substancja %d z %d\n",r.me,it->me); temp.push( make_pair(-(it->prior), r.me) ); //else temp.insert( make_pair(M, r.me) ); // z tymi nikt nie chce zareagowac begins[r.me]=it; // fprintf(stderr,"zakolejkowalem %d z prior. %d\n",r.me,it->prior); } } for (reaction r : fiolki[a]) q[r.me]=false; // w tej petli przeprowadzamy reakcje while(!temp.empty()) { int substance1=temp.top().second; // fprintf(stderr,"priorytet %d\n",-temp.top().first); temp.pop(); if(cap[substance1]==0) continue; // wpp pierwsza substancja moze zareagowac int substance2=begins[substance1]->me; // fprintf(stderr,"mam substancje %d o pojemnosci %d\n",substance2,cap[substance2]); if( cap[substance2] != 0 ) { // fprintf(stderr,"mietolimy %d z %d\n",substance1,substance2); osad+=react(substance1,substance2); } begins[substance1]++; if( begins[substance1]->other==substance1 ) temp.push( make_pair(-(begins[substance1]->prior), substance1) ); } fiolki[b].insert( fiolki[a].begin(),fiolki[a].end() ); } printf("%lld\n", osad); return 0; } |
English