最大流模板 ISAP
邻接矩阵:
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #define MIN(a,b) (a)<(b)?(a):(b) 5 const int M = 110; 6 const int inf = 0x3fffffff; 7 int n, m, A[1010], pre[1010]; 8 int remain[M][M], h[M], vh[M], S, T, N;39 int DFS( int u, int flow ) 40 { 41 if( u == T ) return flow;//找到增广路 42 int tmp = h[u]+1, sum = flow; //更新当前点层数 43 for(int v = 0; v < N; v++) 44 { 45 if( remain[u][v] && h[u] == h[v]+1 ) //允许弧,且一层差别 46 { 47 int p = DFS( v, MIN( sum, remain[u][v]) ); 48 remain[u][v] -= p; remain[v][u] += p; sum -= p; //更新残留网络 49 if( sum == 0 || h[S] == N ) return flow-sum; 50 } 51 } 52 for(int v = 0; v < N; v++) 53 if( remain[u][v] ) 54 tmp = MIN( tmp, h[v] ); 55 if( !( --vh[ h[u] ] ) ) h[S] = N; //间隙优化,当出现断层即可判定无增广路 56 else ++vh[ h[u] = tmp+1 ]; 57 return flow-sum; 58 } 59 void sap() 60 { 61 int maxflow = 0; 62 memset( h, 0, sizeof(h)); 63 memset( vh, 0, sizeof(vh)); 64 vh[S] = N; //0层节点数量为N 65 while( h[S] < N ) maxflow += DFS( S, inf ); 66 printf("%d\n", maxflow ); 67 }
静态链表:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include<vector> 7 using namespace std; 8 9 const int inf = 0x3f3f3f3f; 10 int n, m, K; 11 int N, M, S, T; 12 bool mp[100][100]; 13 int vh[500], h[500]; 14 15 struct node{ 16 int v, f, nxt; 17 }edge[250000]; 18 int head[500], idx; 19 20 void addedge(int u,int v,int f){ 21 edge[idx].v = v; edge[idx].f = f; 22 edge[idx].nxt = head[u]; head[u] = idx++; 23 24 edge[idx].v = u; edge[idx].f = 0; 25 edge[idx].nxt = head[v]; head[v] = idx++; 26 } 27 void CreateGraph(int L){ 28 idx = 0; 29 memset(head,-1,sizeof(head)); 30 31 for(int x = 1; x <= n; x++){ 32 addedge( S, x, L ); 33 for(int y = 1; y <= m; y++){ 34 if( mp[x][y] ) addedge(x,n+y,1); 35 else addedge(x,m+n+y,1); 36 } 37 } 38 for(int y = 1; y <= m; y++){ 39 addedge( n+y, n+2*m+y , n ); 40 addedge( n+m+y, n+2*m+y, K ); 41 addedge( n+2*m+y, T, L ); 42 } 43 } 44 int dfs(int u,int flow){ 45 if( u == T ) return flow; 46 int tmp = h[u]+1, sum = flow; 47 for(int i = head[u]; ~i; i = edge[i].nxt ){ 48 if( edge[i].f && (h[edge[i].v]+1==h[u]) ){ 49 int p = dfs( edge[i].v , min(sum,edge[i].f) ); 50 edge[i].f -= p; edge[i^1].f += p; sum -= p; 51 if( sum == 0 || h[S] == N ) return flow-sum; 52 } 53 } 54 for(int i = head[u]; ~i; i = edge[i].nxt ) 55 if( edge[i].f ) tmp = min( tmp, h[ edge[i].v ] ); 56 if( --vh[ h[u] ] == 0 ) h[S] = N; 57 else ++vh[ h[u]=tmp+1 ]; 58 return flow-sum; 59 } 60 int SAP(){ 61 int maxflow = 0; 62 memset(vh,0,sizeof(vh)); 63 memset(h,0,sizeof(h)); 64 vh[S] = N; 65 while( h[S] < N ) maxflow += dfs( S, inf ); 66 return maxflow; 67 }