POJ 3469 Dual Core CPU <Dinic + 最小割 + 最大流>

来源:互联网 发布:python官网下载有64 编辑:程序博客网 时间:2024/05/21 17:15

传送门:http://poj.org/problem?id=3469


题意:要在由核A核B组成的双核CPU上运行N个模块。模块i在核A执行花费时间为Ai,在核B花费时间为Bi。有M个相互之间需要进行数据交换(ai,bi),如果这两个在同一个核,不计算,否则需花费wi。求所要花费最小多少?

分析:最小割转化为最大流

Dinic求最大流,VElogV,数据量大,其他方法容易TLE

#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 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 dfs(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 = dfs(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 s,int t){    int ans = 0;    while(bfs(s,t))        ans += dfs(s,INF);    return ans;}void init(){     memset(head, -1, sizeof(head));     tot = 0;}int main(){    int s,t;    while(scanf("%d%d", &n, &m) != EOF)    {        int a, b, c;        s = 0,t=n+1;        init();        for(int i = 1; i <= n; i++)        {            scanf("%d%d", &a, &b);            add_edge(s, i, a);            add_edge(i, t, 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(s,t));    }    return 0;}


0 0
原创粉丝点击