1 //isap 2 struct isap_edge{ 3 int from, to, next, val; 4 }isap_e[MAXM]; 5 6 int isap_cnt, isap_h[MAXN]; 7 8 void isap_init(){ 9 isap_cnt = 0; 10 memset( isap_h, -1, sizeof( isap_h ) ); 11 } 12 13 void isap_add( int from, int to, int v1, int v2 ){ 14 isap_e[isap_cnt].from = from; 15 isap_e[isap_cnt].to = to; 16 isap_e[isap_cnt].val = v1; 17 isap_e[isap_cnt].next = isap_h[from]; 18 isap_h[from] = isap_cnt++; 19 20 swap( from, to ); 21 22 isap_e[isap_cnt].from = from; 23 isap_e[isap_cnt].to = to; 24 isap_e[isap_cnt].val = v2; 25 isap_e[isap_cnt].next = isap_h[from]; 26 isap_h[from] = isap_cnt++; 27 } 28 29 int isap( int s, int t, int n ){ 30 int Q[MAXN], cnt[MAXN], d[MAXN], low[MAXN], cur[MAXN]; 31 32 int l = 0, r = 0; 33 for( int i = 1; i <= n; i++ ){ 34 d[i] = n; cnt[i] = 0; 35 } 36 cnt[n] = n - 1; cnt[0]++; d[t] = 0; 37 38 Q[r++] = t; 39 while( l < r ){ 40 int v = Q[l++]; 41 for( int i = isap_h[v]; i != -1; i = isap_e[i].next ){ 42 if( d[isap_e[i].to] == n && isap_e[i ^ 1].val > 0 ){ 43 d[isap_e[i].to] = d[v] + 1; 44 cnt[n]--; 45 cnt[d[isap_e[i].to]]++; 46 Q[r++] = isap_e[i].to; 47 } 48 } 49 } 50 51 int max_flow = 0, pos = s, top = 0; low[0] = INF; 52 for( int i = 1; i <= n; i++ ) 53 cur[i] = isap_h[i]; 54 while( d[s] < n ){ 55 int &i = cur[pos]; 56 for( ; i != -1; i = isap_e[i].next ){ 57 if( isap_e[i].val > 0 && d[pos] == d[isap_e[i].to] + 1 ){ 58 low[top + 1] = min( low[top], isap_e[i].val ); 59 Q[++top] = i; 60 pos = isap_e[i].to; 61 break; 62 } 63 } 64 65 if( i != -1 ){ 66 if( pos == t ){ 67 int minf = low[top]; 68 for( int p = 1,i; p <= top; ++p ){ 69 i = Q[p]; 70 isap_e[i].val -= minf; 71 isap_e[i ^ 1].val += minf; 72 } 73 max_flow += minf; 74 pos = s; 75 low[0] = INF; 76 top = 0; 77 } 78 } 79 else{ 80 int old = d[pos]; 81 cnt[old]--; 82 d[pos] = n - 1; 83 for( int i = isap_h[pos]; i != -1; i = isap_e[i].next ) 84 if( isap_e[i].val > 0 && d[pos] > d[isap_e[i].to] ) 85 d[pos] = d[isap_e[i].to]; 86 cnt[++d[pos]]++; 87 if( d[pos] < n ) 88 cur[pos] = isap_h[pos]; 89 if( pos != s ){ 90 pos = isap_e[Q[top]].from; 91 --top; 92 } 93 if( cnt[old] == 0 ) 94 break; 95 } 96 } 97 return max_flow; 98 }