zoj 3229 上下界网络最大可行流带输出方案
收获:
1. 上下界网络流求最大流步骤:
1) 建出无环无汇的网络,并看是否存在可行流
2) 如果存在,那么以原来的源汇跑一次最大流
3) 流量下界加上当前网络每条边的流量就是最大可行流了.
2. 输出方案:
可以把边的位置信息一起存在边表中,求完最大流后遍历一下边,把信息更新过去.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #define min(a,b) ((a)<(b)?(a):(b)) 4 #define oo 0x3f3f3f3f 5 #define N 1500 6 #define M 500000 7 8 struct Dinic { 9 int n, src, dst; 10 int head[N], dest[M], flow[M], next[M], info[M][2], etot; 11 int cur[N], dep[N], qu[N], bg, ed; 12 void init( int n, int src, int dst ) { 13 this->n = n; 14 this->src = src; 15 this->dst = dst; 16 etot = 0; 17 memset( head, -1, sizeof(head) ); 18 } 19 void adde( int i, int j, int u, int v, int f ) { 20 next[etot]=head[u],flow[etot]=f,dest[etot]=v,info[etot][0]=i,info[etot][1]=j; head[u]=etot++; 21 next[etot]=head[v],flow[etot]=0,dest[etot]=u,info[etot][0]=-1,info[etot][1]=-1; head[v]=etot++; 22 } 23 bool bfs() { 24 memset( dep, 0, sizeof(dep) ); 25 qu[bg=ed=1] = src; 26 dep[src] = 1; 27 while( bg<=ed ) { 28 int u=qu[bg++]; 29 for( int t=head[u]; t!=-1; t=next[t] ) { 30 int v=dest[t], f=flow[t]; 31 if( f && !dep[v] ) { 32 dep[v] = dep[u]+1; 33 qu[++ed] = v; 34 } 35 } 36 } 37 return dep[dst]; 38 } 39 int dfs( int u, int a ) { 40 if( u==dst || a==0 ) return a; 41 int remain=a, past=0, na; 42 for( int &t=cur[u]; t!=-1; t=next[t] ) { 43 int v=dest[t], &f=flow[t], &vf=flow[t^1]; 44 if( f && dep[v]==dep[u]+1 && (na=dfs(v,min(remain,f))) ) { 45 f -= na; 46 vf += na; 47 remain -= na; 48 past += na; 49 if( !remain ) break; 50 } 51 } 52 return past; 53 } 54 int maxflow() { 55 int f=0; 56 while( bfs() ) { 57 memcpy( cur, head, sizeof(cur) ); 58 f += dfs(src,oo); 59 } 60 return f; 61 } 62 }D; 63 struct Btop { 64 int n; 65 int head[N], dest[M], bval[M], tval[M], next[M], info[M][2], etot; 66 int si[N], so[N]; 67 void init( int n ) { 68 this->n = n; 69 etot = 0; 70 memset( head, -1, sizeof(head) ); 71 memset( si, 0, sizeof(si) ); 72 memset( so, 0, sizeof(so) ); 73 } 74 void adde( int i, int j, int u, int v, int b, int t ) { 75 next[etot]=head[u],tval[etot]=t,bval[etot]=b,dest[etot]=v; 76 info[etot][0]=i, info[etot][1]=j; 77 si[v] += b, so[u] += b; 78 head[u]=etot++; 79 } 80 bool ok() { 81 int src=n+1, dst=n+2; 82 D.init( dst, src, dst ); 83 for( int u=1; u<=n; u++ ) 84 for( int t=head[u]; t!=-1; t=next[t] ) { 85 int v=dest[t]; 86 D.adde( info[t][0], info[t][1], u, v, tval[t]-bval[t] ); 87 } 88 int sum = 0; 89 for( int u=1; u<=n; u++ ) { 90 if( si[u]>so[u] ) { 91 D.adde( -1, -1, src, u, si[u]-so[u] ); 92 sum += si[u]-so[u]; 93 } else if( so[u]>si[u] ) { 94 D.adde( -1, -1, u, dst, so[u]-si[u] ); 95 } 96 } 97 return sum==D.maxflow(); 98 } 99 }B; 100 101 int n, m; 102 int c[375]; 103 int ans[375][110], tot; 104 105 int main() { 106 while( scanf( "%d%d", &n, &m ) == 2 ) { 107 int src=n+m+1, dst=src+1; 108 B.init(dst); 109 for( int i=1,g; i<=m; i++ ) { 110 scanf( "%d", &g ); 111 B.adde( -1, -1, n+i, dst, g, oo ); 112 } 113 memset( ans, 0, sizeof(ans) ); 114 tot = 0; 115 for( int i=1,d; i<=n; i++ ) { 116 scanf( "%d%d", c+i, &d ); 117 B.adde( -1, -1, src, i, 0, d ); 118 for( int j=1,t,l,r; j<=c[i]; j++ ) { 119 scanf( "%d%d%d", &t, &l, &r ); 120 t++; 121 B.adde( i, j, i, n+t, l, r ); 122 ans[i][j] = l; 123 tot += l; 124 } 125 } 126 B.adde( -1, -1, dst, src, 0, oo ); 127 bool ok = B.ok(); 128 if( !ok ) { 129 printf( "-1\n" ); 130 } else { 131 D.src=src; 132 D.dst=dst; 133 D.maxflow(); 134 for( int t=0; t<D.etot; t++ ) { 135 int i=D.info[t][0], j=D.info[t][1]; 136 if( ~i && ~j ) { 137 ans[i][j] += D.flow[t^1]; 138 tot += D.flow[t^1]; 139 } 140 } 141 printf( "%d\n", tot ); 142 for( int i=1; i<=n; i++ ) 143 for( int j=1; j<=c[i]; j++ ) 144 printf( "%d\n", ans[i][j] ); 145 } 146 printf( "\n" ); 147 } 148 }