poj 3469 Dual Core CPU 最小割

构图思路:

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

 

posted @ 2013-07-07 13:06  yefeng1627  阅读(259)  评论(0编辑  收藏  举报

Launch CodeCogs Equation Editor