tcbpg

Untitled

Sep 20th, 2011
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.79 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <map>
  4. #include <cstring>
  5. #include <cstdlib>
  6. #include <queue>
  7.  
  8. #define forn(i, n) for(int i = 0; i < (int) (n); i++)
  9. #define forsn(i, s, n) for(int i = (int) (s); i < (int) (n); i++)
  10. #define dforn(i, n) for(int i = ((int) n) - 1; i >= 0; i--)
  11. #define forall(i, c) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
  12.  
  13. using namespace std;
  14.  
  15. //DINITZ
  16. #define INF 1000000000
  17. #define MAX_M 1000000
  18. #define MAX_N 45000
  19.  
  20. int v[2*MAX_M], l[2*MAX_M];
  21. long c[2*MAX_M];
  22. int sz[2*MAX_N], po[MAX_N], r[MAX_N], n, S, T;
  23.  
  24. typedef map<int, long> Mii;
  25. Mii CAP[MAX_N];
  26.  
  27. void iniG(){
  28.     n = 0;
  29.     memset(sz, 0, sizeof(sz));
  30.     forn(i, MAX_N) CAP[i].clear();
  31. }
  32.  
  33. void aEje(int d, int h, long cap){
  34.     if(d == h) return;
  35.     n = max(n, max(d, h));
  36.     pair<Mii::iterator, bool> par = CAP[d].insert(make_pair(h, 0));
  37.     if(par.second){
  38.         CAP[h][d] = 0;
  39.         sz[d]++, sz[h]++;
  40.     }
  41.  
  42.     par.first->second += max(cap, (long) 0);
  43. }
  44.  
  45. void _aEje(int d, int h, long capDH, long capHD){
  46. #define ASIG(d, h, cap) {v[po[d]] = h; c[po[d]] = cap; l[po[d]] = po[h]; }
  47.  
  48.     ASIG(d, h, capDH);
  49.     ASIG(h, d, capHD);
  50.     po[d]++, po[h]++;
  51. }
  52.  
  53. void _iniG(){
  54.     po[0] = 0;
  55.     forn(i, n-1) po[i+1] = po[i]+sz[i];
  56.     forn(u, n) forall(v, CAP[u])
  57.         if(u < v->first) _aEje(u, v->first, v->second, CAP[v->first][u]);
  58. }
  59.  
  60. long aumentar(){
  61.     forn(i, n) r[i] = -1;
  62.     r[S] = 0;
  63.     queue<int> q;
  64.     q.push(S);
  65.     while(!q.empty()){
  66.         int x = q.front(); q.pop();
  67.         int d = r[x]+1, b = po[x];
  68.         if(r[T] >= 0 && d > r[T]) break;
  69.         forsn(j, b, b+sz[x])
  70.         if(c[j] > 0 && r[v[j]] < 0){
  71.             r[v[j]] = d;
  72.             q.push(v[j]);
  73.         }
  74.     }
  75.  
  76.     long res = 0;
  77.     static int path[MAX_N]; path[0] = S;
  78.     static int p[MAX_N], ind[MAX_N];
  79.     memset(p, -1, sizeof(p));
  80.  
  81.     int pp = 0;
  82.     while(pp >= 0){
  83.         int x = path[pp];
  84.         if(x == T){
  85.             long f = INF;
  86.             int pri = 0;
  87.  
  88.             dforn(i, pp) if(c[ind[i]] <= f) f=c[ind[i]],pri=i;
  89.             forn(i, pp) c[ind[i]] -= f, c[l[ind[i]]] += f;
  90.  
  91.             res+= f;
  92.             pp = pri;
  93.         }else if(++p[x] < sz[x]){
  94.             int j = po[x]+p[x];
  95.             if(p[v[j]] < 0 && c[j] > 0 && r[v[j]] == 1 + r[x])
  96.                 ind[pp] = j, path[++pp] = v[j];
  97.         }else pp--;
  98.     }
  99.  
  100.     return res;
  101. }
  102.  
  103. long flujo(int ss, int tt){
  104.     S = ss; T = tt;
  105.     n = max(n, max(S, T))+1;
  106.     _iniG();
  107.     forn(i, n) po[i] -= sz[i];
  108.  
  109.     long res = 0, c;
  110.     do{ res += (c = aumentar());}while(c > 0);
  111.     return res;
  112. }
  113.  
  114. //FIN DINITZ
  115.  
  116. int main(){
  117. #ifdef ACM
  118.     freopen("test.in", "r", stdin);
  119. #endif
  120.  
  121.     int g, f;
  122.     while(scanf("%d %d\n", &g, &f) && (g != 0 || f != 0)){
  123.         iniG();
  124.         forn(i, g){
  125.             int pref; scanf("%d", &pref);
  126.             if(pref) aEje(0, 1+i, 1); else aEje(1+i, 1+g, 1);
  127.         }
  128.  
  129.         forn(i, f){
  130.             int a, b;
  131.             scanf("%d %d", &a, &b); a--, b--;
  132.  
  133.             aEje(a, b, 1); aEje(b, a, 1);
  134.         }
  135.  
  136.         long fluj = flujo(0, 1+g);
  137.         printf("%ld\n", fluj);
  138.     }
  139.  
  140.     return 0;
  141. }
Advertisement
Add Comment
Please, Sign In to add comment