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 }