POJ 3469 Dual Core CPU(最小割模型的建立)

分析

这类问题的一遍描述,把一些对象分成两组,划分有一些代价,问最小代价。一般性的思路是,

把这两组看成是S点和T点,把划分的代价和割边的容量对应起来求最小割。

把S和可模版tem之间到达关系看作是属于核A,对称地,T对应B。模块tem安装在A上代价Ai,就是割断tem和T,连一条tem到T的容量为Ai的边。

相应地,对于Bi,连一条S到tem容量为Bi的边。当ai安装在A上,bi安装在B上,也就是s - ai, bi - t(-表示可到达),这时候如果有额外花费wi

那么ai - bi之间连上容量为wi的边,反过来bi和ai对换一下也是类似的。

输入很大,光是I/O就能优化1s,ISAP会更快。

/*********************************************************
*            ------------------                          *
*   author AbyssalFish                                   *
**********************************************************/
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
using namespace std;

const int maxv = 2e4+2, maxe = 4e5+maxv*4;
int hd[maxv],to[maxe],nx[maxe],ec,cap[maxe];
#define eachEage int i = hd[u]; ~i; i = nx[i]
inline void add(int u,int v, int cp)
{
    nx[ec] = hd[u];
    to[ec] = v;
    cap[ec] = cp;
    hd[u] = ec++;
}
inline void Add(int u,int v,int cp)
{
    add(u,v,cp); add(v,u,0);
}
int lv[maxv], q[maxv];
bool vis[maxv];
int S,T;
bool bfs()
{
    memset(vis,0,sizeof(bool)*(T+1));
    int l = 0, r = 0;
    lv[q[r++] = S] = 0;
    vis[S] = true;
    while(l<r){
        int u = q[l++];
        for(eachEage){
            int v = to[i];
            if(!vis[v] && cap[i]){
                lv[q[r++] = v] = lv[u] + 1;
                vis[v] = true;
            }
        }
    }
    return vis[T];
}

int cur[maxv];

int aug(int u,int a)
{
    if(u == T || !a) return a;
    int flow = 0,f;
    for(int &i = cur[u]; ~i; i = nx[i]){
        int v = to[i];
        if(lv[v] == lv[u]+1 && (f = aug(v, min(a,cap[i])))){
            flow += f; a -= f;
            cap[i] -= f; cap[i^1] += f;
            if(!a) break;
        }
    }
    return flow;
}

int maxFlow()
{
    int flow = 0;
    while(bfs()){
        memcpy(cur,hd,sizeof(int)*(T+1));
        flow += aug(S,1<<30);
    }
    return flow;
}

inline int read()
{
    int ret; char c; while(c = getchar(),c<'0'||c>'9');
    ret = c-'0';
    while(c = getchar(),c>='0'&&c<='9') ret = ret*10 + c-'0';
    return ret;
}

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    int n, m;
    while(~scanf("%d%d",&n,&m)){
        S = 0; T = n+1;
        memset(hd,0xff,sizeof(int)*(T+1)); ec = 0;
        for(int i = 1; i <= n; i++){
            Add(i,T,read());
            Add(S,i,read());
        }
        for(int i = 0; i < m; i++){
            int a = read(),b = read(),w = read();
            add(a,b,w); add(b,a,w);
        }
        printf("%d
",maxFlow());
    }

    return 0;
}
原文地址:https://www.cnblogs.com/jerryRey/p/4947596.html