poj 3469 Dual Core CPU(dinic算法)

来源:互联网 发布:java基础知识总结 编辑:程序博客网 时间:2024/06/16 21:38

题意:

有一些模块(modules)和一个双核处理器,一个模块可以在任意一个核上处理,每个核对应每个模块有个开销。现在有一些模块间需要数据交换,如果需要数据交换的模块在一个核上处理,则不需要额外开销,否则需要加上一个开销。现在需要完成所有模块,问最小需要多少开销。

如果没有这个额外的开销,那么每个模块只要选择开销小的那个核就行了。额外的开销给选择加上了限制。

题解:

最小割模型。

S和T分别表示两个核,每个模块和S,T连边求最小割就是了~

#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <cmath>#include <vector>#include <set>#include <list>#include <queue>#include <map>#include <stack>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-3#define maxn 200010#define MOD 1000000007struct Edge{    int to, val, next;} edge[2000000];int n, m, tot;int head[20100], level[20100], cur[20100];void add_edge(int from, int to, int val){    edge[tot].to = to;    edge[tot].val = val;    edge[tot].next = head[from];    head[from] = tot++;    edge[tot].to = from;    edge[tot].val = 0;    edge[tot].next = head[to];    head[to] = tot++;}int bfs(int s,int t){    queue<int> que;    que.push(s);    memset(level,-1,sizeof(level));    level[s] = 0;    while(!que.empty())    {        int v = que.front();        que.pop();        int u = head[v];        for(; u != -1; u = edge[u].next)            if(edge[u].val > 0 && level[edge[u].to] == -1)        {            level[edge[u].to] = level[v] + 1;            que.push(edge[u].to);            if(edge[u].to == t)                return 1;        }    }    return 0;}int Find(int u,int cnt){    if(u == n+1)        return cnt;    int result = 0,tmp = 0;    for(int i = head[u]; i != -1 && result < cnt; i = edge[i].next)        if(edge[i].val > 0 && level[edge[i].to] == level[u] + 1)        {            tmp = Find(edge[i].to,min(edge[i].val,cnt - result));            edge[i].val -= tmp;            edge[i^1].val += tmp;            result += tmp;        }    if(!result)        level[u] = -1;    return result;}int dinic(){    int ans = 0;    while(bfs(0,n+1))        ans += Find(0,INF);    return ans;}int main(){    while(scanf("%d%d", &n, &m) != EOF)    {        int a, b, c;        memset(head, -1, sizeof(head));        tot = 0;        for(int i = 1; i <= n; i++)        {            scanf("%d%d", &a, &b);            add_edge(0, i, a);            add_edge(i, n+1, b);        }        for(int i = 1; i <= m; i++)        {            scanf("%d%d%d", &a, &b,&c);            add_edge(a, b, c);            add_edge(b, a, c);        }        printf("%d\n", dinic());    }    return 0;}

0 0