#include <iostream> #include <vector> #include <set> #include <algorithm> #define ll long long using namespace std; //nie mam zielonego pojecia czemu nie dziala struct doReakcji { int kto, zkim, nr; doReakcji(int a, int b, int c):kto(a), zkim(b), nr(c){} }; bool operator < (doReakcji a, doReakcji b) {return a.zkim<b.zkim;} bool porownajPoNumerze( doReakcji a, doReakcji b) {return a.nr<b.nr;} struct fiolka { set<int> substancje; set<doReakcji> reakcje; }; fiolka tab[200009]; ll gramy[200009]; ll wynik=0; vector<pair<int, int> >kroki; vector<pair<int, int> >pary; void junion(int a, int b); int main() { int lfiolek, lkrokow, lpar; cin>>lfiolek>>lkrokow>>lpar; for(int n=1; n<=lfiolek; n++) { tab[n].substancje.insert(n); cin>>gramy[n]; } int tmpa, tmpb; for(int n=0; n<lkrokow; n++) { cin>>tmpa>>tmpb; kroki.push_back(make_pair(tmpa, tmpb)); } for(int n=0; n<lpar; n++) { cin>>tmpa>>tmpb; // pary.push_back(make_pair(tmpa, tmpb)); tab[tmpa].reakcje.insert(doReakcji(tmpa, tmpb, n+1)); tab[tmpb].reakcje.insert(doReakcji(tmpb, tmpa, n+1)); } for(int n=0; n<lkrokow; n++) { // cout<<" "<<kroki[n].first<<" "<<kroki[n].second<<endl; junion(kroki[n].first, kroki[n].second); // cout<<wynik<<endl; } cout<<wynik<<endl; } void junion(int b, int a) { vector<doReakcji> bedzieReagowac; int swapped=0; // if(tab[a].substancje.size()<tab[b].substancje.size()) {swap(a, b); swapped=1;} for(auto it=tab[b].substancje.begin(); it!=tab[b].substancje.end(); it++) { for(auto n=tab[a].reakcje.lower_bound(doReakcji(0, *it, 0)); n!=tab[a].reakcje.upper_bound(doReakcji(0, *it, 0)); n++) { bedzieReagowac.push_back(*n); // tab[a].reakcje.erase(*n); //not sure } } sort(bedzieReagowac.begin(), bedzieReagowac.end(), porownajPoNumerze); for(int n=0; n<bedzieReagowac.size(); n++) { // cout<<" "<<bedzieReagowac[n].kto<<" reaguje z "<<bedzieReagowac[n].zkim<<endl; int tmp=min(gramy[bedzieReagowac[n].zkim], gramy[bedzieReagowac[n].kto]); // cout<<"tmp="<<tmp<<endl; wynik+=2*tmp; gramy[bedzieReagowac[n].zkim]-=tmp; gramy[bedzieReagowac[n].kto]-=tmp; // if(gramy[bedzieReagowac[n].zkim]==0) // { // if( tab[b].substancje.count(bedzieReagowac[n].zkim)>0 ) // tab[b].substancje.erase(bedzieReagowac[n].zkim); // } // if(gramy[bedzieReagowac[n].kto]==0) // { // if( tab[a].substancje.count(bedzieReagowac[n].kto)>0 ) // tab[a].substancje.erase(bedzieReagowac[n].kto); // } } if(swapped) swap(a,b); tab[a].substancje.insert(tab[b].substancje.begin(), tab[b].substancje.end()); tab[a].reakcje.insert(tab[b].reakcje.begin(), tab[b].reakcje.end()); // tab[b].substancje.clear(); // tab[b].reakcje.clear(); // cout<<"elementy zbioru "<<a<<": "; // for(auto n= tab[a].substancje.begin();n!=tab[a].substancje.end(); n++) // { // cout<<*n<<" "; // } // cout<<endl; }
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 | #include <iostream> #include <vector> #include <set> #include <algorithm> #define ll long long using namespace std; //nie mam zielonego pojecia czemu nie dziala struct doReakcji { int kto, zkim, nr; doReakcji(int a, int b, int c):kto(a), zkim(b), nr(c){} }; bool operator < (doReakcji a, doReakcji b) {return a.zkim<b.zkim;} bool porownajPoNumerze( doReakcji a, doReakcji b) {return a.nr<b.nr;} struct fiolka { set<int> substancje; set<doReakcji> reakcje; }; fiolka tab[200009]; ll gramy[200009]; ll wynik=0; vector<pair<int, int> >kroki; vector<pair<int, int> >pary; void junion(int a, int b); int main() { int lfiolek, lkrokow, lpar; cin>>lfiolek>>lkrokow>>lpar; for(int n=1; n<=lfiolek; n++) { tab[n].substancje.insert(n); cin>>gramy[n]; } int tmpa, tmpb; for(int n=0; n<lkrokow; n++) { cin>>tmpa>>tmpb; kroki.push_back(make_pair(tmpa, tmpb)); } for(int n=0; n<lpar; n++) { cin>>tmpa>>tmpb; // pary.push_back(make_pair(tmpa, tmpb)); tab[tmpa].reakcje.insert(doReakcji(tmpa, tmpb, n+1)); tab[tmpb].reakcje.insert(doReakcji(tmpb, tmpa, n+1)); } for(int n=0; n<lkrokow; n++) { // cout<<" "<<kroki[n].first<<" "<<kroki[n].second<<endl; junion(kroki[n].first, kroki[n].second); // cout<<wynik<<endl; } cout<<wynik<<endl; } void junion(int b, int a) { vector<doReakcji> bedzieReagowac; int swapped=0; // if(tab[a].substancje.size()<tab[b].substancje.size()) {swap(a, b); swapped=1;} for(auto it=tab[b].substancje.begin(); it!=tab[b].substancje.end(); it++) { for(auto n=tab[a].reakcje.lower_bound(doReakcji(0, *it, 0)); n!=tab[a].reakcje.upper_bound(doReakcji(0, *it, 0)); n++) { bedzieReagowac.push_back(*n); // tab[a].reakcje.erase(*n); //not sure } } sort(bedzieReagowac.begin(), bedzieReagowac.end(), porownajPoNumerze); for(int n=0; n<bedzieReagowac.size(); n++) { // cout<<" "<<bedzieReagowac[n].kto<<" reaguje z "<<bedzieReagowac[n].zkim<<endl; int tmp=min(gramy[bedzieReagowac[n].zkim], gramy[bedzieReagowac[n].kto]); // cout<<"tmp="<<tmp<<endl; wynik+=2*tmp; gramy[bedzieReagowac[n].zkim]-=tmp; gramy[bedzieReagowac[n].kto]-=tmp; // if(gramy[bedzieReagowac[n].zkim]==0) // { // if( tab[b].substancje.count(bedzieReagowac[n].zkim)>0 ) // tab[b].substancje.erase(bedzieReagowac[n].zkim); // } // if(gramy[bedzieReagowac[n].kto]==0) // { // if( tab[a].substancje.count(bedzieReagowac[n].kto)>0 ) // tab[a].substancje.erase(bedzieReagowac[n].kto); // } } if(swapped) swap(a,b); tab[a].substancje.insert(tab[b].substancje.begin(), tab[b].substancje.end()); tab[a].reakcje.insert(tab[b].reakcje.begin(), tab[b].reakcje.end()); // tab[b].substancje.clear(); // tab[b].reakcje.clear(); // cout<<"elementy zbioru "<<a<<": "; // for(auto n= tab[a].substancje.begin();n!=tab[a].substancje.end(); n++) // { // cout<<*n<<" "; // } // cout<<endl; } |