# poj 2125 Destroying The Graph 最小割+方案输出

1.将所有顶点v拆成两个点， v1,v2

2.源点S与v1连边，容量为 W-

3.v2与汇点连边，容量为 W+

4.对图中原边( a, b ), 连边 (a1,b2)，容量为正无穷大

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

const int MAXN = 220;
const int MAXM = 5050;
const int inf = 0x3f3f3f3f;
int A[MAXN], B[MAXN];
struct Edge{
int u, v, f, nxt;
}edge[250000];
int n, m;
int S, T, N;

edge[idx].u = u, edge[idx].v = v, edge[idx].f = f;
edge[idx].u = v, edge[idx].v = u, edge[idx].f = 0;
}

int h[MAXN], vh[MAXN];
int dfs(int u,int flow){
if(u == T) return flow;
int tmp = h[u]+1, sum = flow;
for(int i = head[u]; ~i; i = edge[i].nxt){
if( edge[i].f && (h[edge[i].v]+1 == h[u]) ){
int p = dfs( edge[i].v, min(sum,edge[i].f));
edge[i].f-=p, edge[i^1].f+=p, sum-=p;
if( sum==0 || h[S]==N ) return flow-sum;
}
}
for(int i = head[u]; ~i; i = edge[i].nxt)
if( edge[i].f ) tmp = min( tmp, h[edge[i].v] );
if( --vh[ h[u] ] == 0 ) h[S] = N;
else ++vh[ h[u]=tmp+1 ];
return flow-sum;
}
int sap(){
int maxflow = 0;
memset(h,0,sizeof(h));
memset(vh,0,sizeof(vh));
vh[0] = N;
while( h[S] < N ) maxflow += dfs( S, inf );
return maxflow;
}

bool vis[MAXN];
int res[MAXM];

void DFS(int u ){
vis[u] = true;
for(int i = head[u]; ~i; i = edge[i].nxt ){
int v = edge[i].v;
if( !vis[v] && edge[i].f )
DFS( v );
}
}
void solve(){
int maxflow = sap();
printf("%d\n", maxflow );
memset( vis,0,sizeof(vis));
DFS( S );

int cnt = 0;
for(int i = 0; i < idx; i += 2){
int u = edge[i].u, v = edge[i].v;
if( vis[u] && !vis[v] && (edge[i].f == 0) )
res[cnt++] = i;
}
printf("%d\n", cnt );
for(int i = 0; i < cnt; i++ ){
int u = edge[ res[i] ].u, v = edge[ res[i] ].v;
if( u == S ) printf("%d -\n", v);
else printf("%d +\n", u-n );
}
}

int main(){
while( scanf("%d%d",&n,&m) != EOF ){
S = 0, T = 2*n+1, N = 2*n+2; idx = 0;

for(int i = 1; i <= n; i++ )
scanf("%d", &A[i]);
for(int i = 1; i <= n; i++ )
scanf("%d", &B[i]);
int a, b;
for(int i = 0; i < m; i++ ){
scanf("%d%d", &a,&b);
}
for(int i = 1; i <= n; i++){
AddEdge( S, i, B[i] ); // - out
AddEdge( n+i, T, A[i] );// + in
}
solve();
}
return 0;
}
View Code

posted @ 2013-07-07 12:22  yefeng1627  阅读(873)  评论(0编辑  收藏  举报