POJ - 3469 Dual Core CPU (最小割)

Posted winter-bamboo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ - 3469 Dual Core CPU (最小割)相关的知识,希望对你有一定的参考价值。

(点击此处查看原题)

题意介绍

在一个由核A和核B组成的双核CPU上执行N个任务,任务i在核A上执行,花费Ai,在核B上执行,花费为Bi,而某两个任务之间可能需要进数据交互,如果两个任务在同一个核上执行,那么数据交互将没有花费,如果在不同核上执行,将产生wi的花费,问将n个任务全部执行产生的最小花费 。

解题思路

题目要求将n个任务分配为两个不同的集合,使得执行n个任务总花费最少,这类的题目我们一般将其转化为最小割问题,即花费最小的代价将n个点分为两部分。建图如下:

1)由源点向每个任务建一条容量为Ai的边

2)由每个任务向汇点建一条容量为Bi的边

3)对于不在同一核上运行的两个任务a,b,将产生额外的w花费,我们在a,b之间建两条容量为w的边,分为是a->b,b->a

最后我们在构建的图中跑最小割并输出最小割即可。

代码区

技术图片
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip>

#define bug cout << "**********" << endl
#define show(x, y) cout<<"["<<x<<","<<y<<"] "
#define LOCAL = 1;
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const int Max = 4e6 + 10;

struct Edge

    int to, flow, next;
 edge[Max << 1];

int n, m, s, t;
int head[Max], tot;
int dis[Max], cur[Max];

void init()

    memset(head, -1, sizeof(head));
    tot = 0;
    s = 0;
    t = n + 1;


void add(int u, int v, int flow)

    edge[tot].to = v;
    edge[tot].flow = flow;
    edge[tot].next = head[u];
    head[u] = tot++;


bool bfs()

    memset(dis, -1, sizeof(dis));
    queue<int> q;
    dis[s] = 0;
    q.push(s);
    while (!q.empty())
    
        int u = q.front();
        q.pop();
        for (int i = head[u]; i != -1; i = edge[i].next)
        
            int v = edge[i].to;
            if (edge[i].flow > 0 && dis[v] == -1)
            
                dis[v] = dis[u] + 1;
                if (v == t)
                    return true;
                q.push(v);
            
        
    
    return false;


int dfs(int u, int flow_in)

    if (u == t)
        return flow_in;
    int flow_out = 0;
    for (int i = cur[u]; i != -1; i = edge[i].next)
    
        cur[u] = i;
        int v = edge[i].to;
        if (dis[v] == dis[u] + 1 && edge[i].flow > 0)
        
            int flow = dfs(v, min(flow_in, edge[i].flow));
            if (flow == 0)
                continue;
            flow_in -= flow;
            flow_out += flow;
            edge[i].flow -= flow;
            edge[i ^ 1].flow += flow;
            if (flow_in == 0)
                break;
        
    
    return flow_out;


int Dinic(int ans)

    int sum = 0;
    while (bfs())
    
        for (int i = 0; i <= ans; i++)
            cur[i] = head[i];
        sum += dfs(s, inf);
    
    return sum;


int main()

#ifdef LOCAL
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    while (scanf("%d%d", &n, &m) != EOF)
    
        init();
        for (int i = 1, a, b; i <= n; i++)
        
            scanf("%d%d", &a, &b);
            add(s, i, a);
            add(i, s, 0);
            add(i, t, b);
            add(t, i, 0);
        
        for(int i =1, u, v, flow; i <= m ;i ++)
        
            scanf("%d%d%d",&u,&v,&flow);
            add(u,v,flow);
            add(v,u,flow);
        
        printf("%d\n",Dinic(n+1));
    
    return 0;
View Code

以上是关于POJ - 3469 Dual Core CPU (最小割)的主要内容,如果未能解决你的问题,请参考以下文章

poj 3469 Dual Core CPU——最小割

POJ 3469.Dual Core CPU 最大流dinic算法模板

[POJ3469]Dual Core CPU(最小割)

POJ 3469 Dual Core CPU(最小割)

POJ 3469 Dual Core CPU ——网络流

POJ 3469(Dual Core CPU-最小割)[Template:网络流dinic V2]