您的位置:首页 > 其它

poj 3469 Dual Core CPU 最小割

2013-07-07 13:06 489 查看
构图思路:

1. 源点S与顶点v连边,容量为A

2. 顶点v与汇点T连边,容量为B

3. 边(a,b,c),则顶点a与顶点b连双向边,容量为c

则最小花费为该图最小割即最大流。

若两个作业分别在不同机器运行,则之间若有边,则必定是满流,否则必定还有增广路。

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

const int inf = 0x3f3f3f3f;
const int MAXN = (int)2e5+10;
int n, m;
int S, T, N;
int head[MAXN], idx;
struct Edge{
int v, f, nxt;
}edge[MAXN<<3];

void AddEdge(int u,int v,int f){
edge[idx].v = v, edge[idx].f = f;
edge[idx].nxt = head[u], head[u] = idx++;
edge[idx].v = u, edge[idx].f = 0;
edge[idx].nxt = head[v], head[v] = idx++;
}

int vh[MAXN], h[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;
}

int main(){
while( scanf("%d%d",&n,&m) != EOF ){

memset(head,-1,sizeof(head));
S = 0, T = n+1, N = n+2; idx = 0;

for(int i = 1; i <= n; i++){
int a, b;
scanf("%d%d",&a,&b);
AddEdge( S, i, a );
AddEdge( i, T, b );
}
for(int i = 0; i < m; i++){
int a, b, c;
scanf("%d%d%d",&a,&b,&c);
AddEdge( a, b, c );
AddEdge( b, a, c );
}
int ans = sap();
printf("%d\n", ans );
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: