POJ 3469_Dual Core CPU

来源:互联网 发布:kmeans python iris 编辑:程序博客网 时间:2024/06/11 14:02

题意:

N个模块可以在A,B两个核上运行,分别需要A[i]和B[i],模块之间需要传递数据,若两个模块在同一核上,则不需要花费,否则需要花费w[i]。问最少需要花费多少?

分析:

用最小的费用将两个对象分成两个集合的问题,常常可以转换为最小割问题。
按照N个模块在哪个核上运行分成两个集合。并建边使最小费用等于最小割的容量,即转化为求图中最大流。

代码:

#include<cstdio>#include<vector>#include<cstring>#include<queue>using namespace std;struct edge{int to, cap, rev;};const int maxm = 20010, INF = 0x3fffffff;int d[maxm], iter[maxm];int s, t;vector<edge>G[maxm];void add_edge(int from, int to, int cap){    G[from].push_back((edge){to, cap, G[to].size()});    G[to].push_back((edge){from, 0, G[from].size()-1});}void bfs(){    memset(d, -1, sizeof(d));    queue<int>q;    d[s] = 0;    q.push(s);    while(!q.empty()){        int v = q.front();q.pop();        for(int i = 0; i <G[v].size(); i++){            edge &e = G[v][i];            if(e.cap>0&&d[e.to]<0){                d[e.to] = d[v] + 1;                q.push(e.to);            }        }    }}int dfs(int v, int f){    if(v==t) return f;    for(int &i = iter[v]; i < G[v].size(); i++){        edge &e = G[v][i];        if(e.cap > 0 && d[v] < d[e.to]){            int tf = dfs(e.to, min(f, e.cap));            if(tf > 0){                e.cap -= tf;                G[e.to][e.rev].cap +=tf;                return tf;            }        }    }    return 0;}int max_flow(){    int flow = 0;    for(;;){        bfs();        if(d[t]<0) return flow;        memset(iter, 0, sizeof(iter));        int f;        while((f = dfs(s, INF))>0){            flow += f;        }    }}int main (void){    int N, M;scanf("%d%d",&N,&M);    s = N + 1, t = s +1;    int A, B;    for(int i = 1; i <= N;i++){        scanf("%d%d",&A,&B);        add_edge(s, i, B);        add_edge(i, t, A);    }    int a, b, w;    for(int i = 0; i < M; i++){        scanf("%d%d%d",&a, &b, &w);        add_edge(a, b, w);        add_edge(b, a, w);    }    printf("%d\n",max_flow());}

输入时少读个数都能过样例。也是奇葩【手动再见】。还是细心细心。

0 0
原创粉丝点击