//Jakub Sygnowski #include <cstdio> #include <set> #include <vector> using namespace std; #define MAXN 200007 #define MAXK 500007 #define F first #define S second typedef pair<int,int> pii; typedef long long ll; set<pii> subs; int n, m, k, pocz; set<int> zawartosc[MAXN]; //F - jaka subs, S - ile set<pair<int, bool> > reakcje[MAXN]; //F - nr reakcji, S - czy mam pierwsza substancje pii poczReakcje[MAXK]; int poczIlosci[MAXN]; ll wynik; pii wykonaj[MAXN]; //vector<int> wszystkieReakcje[MAXN]; struct fiolka { set<int> *sub; set<pair<int, bool> > *reakcje; }fiolki[MAXN]; inline void wywal(int nrFiolki, int subs, int ile){ if (poczIlosci[subs] == ile){ (*(fiolki[nrFiolki].sub)).erase((*(fiolki[nrFiolki].sub)).find(subs)); } poczIlosci[subs] -= ile; } void reaguj(int f1, int s1, int f2, int s2){ int zareagowalo = min(poczIlosci[s1], poczIlosci[s2]); wynik += zareagowalo; wywal(f1, s1, zareagowalo); wywal(f2, s2, zareagowalo); } void przeprowadzReakcje(int skad, int dokad){ if ((*(fiolki[skad].reakcje)).size() > (*(fiolki[dokad].reakcje)).size()){ for(set<pair<int, bool> >::iterator it = fiolki[dokad].reakcje->begin(); it != fiolki[dokad].reakcje->end(); it++){ int mam = poczReakcje[it->first].F; int niemam = poczReakcje[it->first].S; if (!poczIlosci[mam] || !poczIlosci[niemam]){ continue; } if (!(it->second)) swap(mam, niemam); set<int>::iterator drugi = (*(fiolki[skad].sub)).find(niemam); if (drugi == fiolki[skad].sub->end()){ (*(fiolki[skad].reakcje)).insert(*it); continue; } reaguj(skad, niemam, dokad, mam); } fiolki[dokad].reakcje = fiolki[skad].reakcje; } else { for(set<pair<int, bool> >::iterator it = fiolki[skad].reakcje->begin(); it != fiolki[skad].reakcje->end(); it++){ int mam = poczReakcje[it->first].S; int niemam = poczReakcje[it->first].F; if (!poczIlosci[mam] || !poczIlosci[niemam]){ continue; } if (it->second) swap(mam, niemam); set<int>::iterator drugi = (*(fiolki[dokad].sub)).find(niemam); if (drugi == fiolki[dokad].sub->end()){ (*(fiolki[dokad].reakcje)).insert(*it); continue; } reaguj(dokad, niemam, skad, mam); } } } void przelejSubstancje(int skad, int dokad){ if (fiolki[skad].sub->size() <= fiolki[dokad].sub->size()){ for(set<int>::iterator it = fiolki[skad].sub->begin(); it != fiolki[skad].sub->end(); it++){ if (poczIlosci[*it]) (*(fiolki[dokad].sub)).insert(*it); } } else { for(set<int>::iterator it = fiolki[dokad].sub->begin(); it != fiolki[dokad].sub->end(); it++){ if (poczIlosci[*it]) (*(fiolki[skad].sub)).insert(*it); } fiolki[dokad].sub = fiolki[skad].sub; } } void przelej(int skad, int dokad){ przeprowadzReakcje(skad, dokad); przelejSubstancje(skad, dokad); } int main(){ scanf("%d%d%d",&n,&m,&k); for(int i = 0; i < n; i++){ scanf("%d", &pocz); zawartosc[i].insert(i); poczIlosci[i] = pocz; } for(int i = 0; i < m; i++){ scanf("%d%d",&wykonaj[i].F, &wykonaj[i].S); wykonaj[i].F--; wykonaj[i].S--; } for(int i = 0; i < k; i++){ int a, b; scanf("%d%d", &a, &b); a--;b--; poczReakcje[i] = make_pair(a, b); reakcje[a].insert(make_pair(i, true)); reakcje[b].insert(make_pair(i, false)); } for(int i = 0; i < n; i++){ fiolki[i].sub = &(zawartosc[i]); fiolki[i].reakcje = &(reakcje[i]); } for(int i = 0; i < m; i++){ przelej(wykonaj[i].F, wykonaj[i].S); } printf("%lld\n", 2ll * wynik); }
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 | //Jakub Sygnowski #include <cstdio> #include <set> #include <vector> using namespace std; #define MAXN 200007 #define MAXK 500007 #define F first #define S second typedef pair<int,int> pii; typedef long long ll; set<pii> subs; int n, m, k, pocz; set<int> zawartosc[MAXN]; //F - jaka subs, S - ile set<pair<int, bool> > reakcje[MAXN]; //F - nr reakcji, S - czy mam pierwsza substancje pii poczReakcje[MAXK]; int poczIlosci[MAXN]; ll wynik; pii wykonaj[MAXN]; //vector<int> wszystkieReakcje[MAXN]; struct fiolka { set<int> *sub; set<pair<int, bool> > *reakcje; }fiolki[MAXN]; inline void wywal(int nrFiolki, int subs, int ile){ if (poczIlosci[subs] == ile){ (*(fiolki[nrFiolki].sub)).erase((*(fiolki[nrFiolki].sub)).find(subs)); } poczIlosci[subs] -= ile; } void reaguj(int f1, int s1, int f2, int s2){ int zareagowalo = min(poczIlosci[s1], poczIlosci[s2]); wynik += zareagowalo; wywal(f1, s1, zareagowalo); wywal(f2, s2, zareagowalo); } void przeprowadzReakcje(int skad, int dokad){ if ((*(fiolki[skad].reakcje)).size() > (*(fiolki[dokad].reakcje)).size()){ for(set<pair<int, bool> >::iterator it = fiolki[dokad].reakcje->begin(); it != fiolki[dokad].reakcje->end(); it++){ int mam = poczReakcje[it->first].F; int niemam = poczReakcje[it->first].S; if (!poczIlosci[mam] || !poczIlosci[niemam]){ continue; } if (!(it->second)) swap(mam, niemam); set<int>::iterator drugi = (*(fiolki[skad].sub)).find(niemam); if (drugi == fiolki[skad].sub->end()){ (*(fiolki[skad].reakcje)).insert(*it); continue; } reaguj(skad, niemam, dokad, mam); } fiolki[dokad].reakcje = fiolki[skad].reakcje; } else { for(set<pair<int, bool> >::iterator it = fiolki[skad].reakcje->begin(); it != fiolki[skad].reakcje->end(); it++){ int mam = poczReakcje[it->first].S; int niemam = poczReakcje[it->first].F; if (!poczIlosci[mam] || !poczIlosci[niemam]){ continue; } if (it->second) swap(mam, niemam); set<int>::iterator drugi = (*(fiolki[dokad].sub)).find(niemam); if (drugi == fiolki[dokad].sub->end()){ (*(fiolki[dokad].reakcje)).insert(*it); continue; } reaguj(dokad, niemam, skad, mam); } } } void przelejSubstancje(int skad, int dokad){ if (fiolki[skad].sub->size() <= fiolki[dokad].sub->size()){ for(set<int>::iterator it = fiolki[skad].sub->begin(); it != fiolki[skad].sub->end(); it++){ if (poczIlosci[*it]) (*(fiolki[dokad].sub)).insert(*it); } } else { for(set<int>::iterator it = fiolki[dokad].sub->begin(); it != fiolki[dokad].sub->end(); it++){ if (poczIlosci[*it]) (*(fiolki[skad].sub)).insert(*it); } fiolki[dokad].sub = fiolki[skad].sub; } } void przelej(int skad, int dokad){ przeprowadzReakcje(skad, dokad); przelejSubstancje(skad, dokad); } int main(){ scanf("%d%d%d",&n,&m,&k); for(int i = 0; i < n; i++){ scanf("%d", &pocz); zawartosc[i].insert(i); poczIlosci[i] = pocz; } for(int i = 0; i < m; i++){ scanf("%d%d",&wykonaj[i].F, &wykonaj[i].S); wykonaj[i].F--; wykonaj[i].S--; } for(int i = 0; i < k; i++){ int a, b; scanf("%d%d", &a, &b); a--;b--; poczReakcje[i] = make_pair(a, b); reakcje[a].insert(make_pair(i, true)); reakcje[b].insert(make_pair(i, false)); } for(int i = 0; i < n; i++){ fiolki[i].sub = &(zawartosc[i]); fiolki[i].reakcje = &(reakcje[i]); } for(int i = 0; i < m; i++){ przelej(wykonaj[i].F, wykonaj[i].S); } printf("%lld\n", 2ll * wynik); } |