Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <map>
- #include <cstring>
- #include <cstdlib>
- #include <queue>
- #define forn(i, n) for(int i = 0; i < (int) (n); i++)
- #define forsn(i, s, n) for(int i = (int) (s); i < (int) (n); i++)
- #define dforn(i, n) for(int i = ((int) n) - 1; i >= 0; i--)
- #define forall(i, c) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
- using namespace std;
- //DINITZ
- #define INF 1000000000
- #define MAX_M 1000000
- #define MAX_N 45000
- int v[2*MAX_M], l[2*MAX_M];
- long c[2*MAX_M];
- int sz[2*MAX_N], po[MAX_N], r[MAX_N], n, S, T;
- typedef map<int, long> Mii;
- Mii CAP[MAX_N];
- void iniG(){
- n = 0;
- memset(sz, 0, sizeof(sz));
- forn(i, MAX_N) CAP[i].clear();
- }
- void aEje(int d, int h, long cap){
- if(d == h) return;
- n = max(n, max(d, h));
- pair<Mii::iterator, bool> par = CAP[d].insert(make_pair(h, 0));
- if(par.second){
- CAP[h][d] = 0;
- sz[d]++, sz[h]++;
- }
- par.first->second += max(cap, (long) 0);
- }
- void _aEje(int d, int h, long capDH, long capHD){
- #define ASIG(d, h, cap) {v[po[d]] = h; c[po[d]] = cap; l[po[d]] = po[h]; }
- ASIG(d, h, capDH);
- ASIG(h, d, capHD);
- po[d]++, po[h]++;
- }
- void _iniG(){
- po[0] = 0;
- forn(i, n-1) po[i+1] = po[i]+sz[i];
- forn(u, n) forall(v, CAP[u])
- if(u < v->first) _aEje(u, v->first, v->second, CAP[v->first][u]);
- }
- long aumentar(){
- forn(i, n) r[i] = -1;
- r[S] = 0;
- queue<int> q;
- q.push(S);
- while(!q.empty()){
- int x = q.front(); q.pop();
- int d = r[x]+1, b = po[x];
- if(r[T] >= 0 && d > r[T]) break;
- forsn(j, b, b+sz[x])
- if(c[j] > 0 && r[v[j]] < 0){
- r[v[j]] = d;
- q.push(v[j]);
- }
- }
- long res = 0;
- static int path[MAX_N]; path[0] = S;
- static int p[MAX_N], ind[MAX_N];
- memset(p, -1, sizeof(p));
- int pp = 0;
- while(pp >= 0){
- int x = path[pp];
- if(x == T){
- long f = INF;
- int pri = 0;
- dforn(i, pp) if(c[ind[i]] <= f) f=c[ind[i]],pri=i;
- forn(i, pp) c[ind[i]] -= f, c[l[ind[i]]] += f;
- res+= f;
- pp = pri;
- }else if(++p[x] < sz[x]){
- int j = po[x]+p[x];
- if(p[v[j]] < 0 && c[j] > 0 && r[v[j]] == 1 + r[x])
- ind[pp] = j, path[++pp] = v[j];
- }else pp--;
- }
- return res;
- }
- long flujo(int ss, int tt){
- S = ss; T = tt;
- n = max(n, max(S, T))+1;
- _iniG();
- forn(i, n) po[i] -= sz[i];
- long res = 0, c;
- do{ res += (c = aumentar());}while(c > 0);
- return res;
- }
- //FIN DINITZ
- int main(){
- #ifdef ACM
- freopen("test.in", "r", stdin);
- #endif
- int g, f;
- while(scanf("%d %d\n", &g, &f) && (g != 0 || f != 0)){
- iniG();
- forn(i, g){
- int pref; scanf("%d", &pref);
- if(pref) aEje(0, 1+i, 1); else aEje(1+i, 1+g, 1);
- }
- forn(i, f){
- int a, b;
- scanf("%d %d", &a, &b); a--, b--;
- aEje(a, b, 1); aEje(b, a, 1);
- }
- long fluj = flujo(0, 1+g);
- printf("%ld\n", fluj);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment