POJ 3469 Dual Core CPU【最小割】

Description
As more and more computers are equipped with dual core CPU, SetagLilb, the Chief Technology Officer of TinySoft Corporation, decided to update their famous product - SWODNIW.
The routine consists of N modules, and each of them should run in a certain core. The costs for all the routines to execute on two cores has been estimated. Let’s define them as Ai and Bi. Meanwhile, M pairs of modules need to do some data-exchange. If they are running on the same core, then the cost of this action can be ignored. Otherwise, some extra cost are needed. You should arrange wisely to minimize the total cost.
Input
There are two integers in the first line of input data, N and M (1 ≤ N ≤ 20000, 1 ≤ M ≤ 200000) .
The next N lines, each contains two integer, Ai and Bi.
In the following M lines, each contains three integers: a, b, w. The meaning is that if module a and module b don’t execute on the same core, you should pay extra w dollars for the data-exchange between them.
Output
Output only one integer, the minimum total cost.
Sample Input
3 1
1 10
2 10
10 3
2 3 1000
Sample Output
13

题意:有AB双核处理器,有n个任务,给出每个任务在分别在两个核上工作的花费,然后有m行,每行给出两个任务,如果两个任务不在同一个处理核心上工作,那么将有额外的花费。求最小花费?
分析:
题意就是将任务划分成两个集合,典型的最小割问题。让源点连向模块权值为在A核的花费,模块连向汇点权值为在B核的花费,模块和模块之间建边权值为额外花费。割边就表示模块在A和在B和绑定模块不在同核的花费之和,就是最小花费。
*有可能RE但是运行结果是TLE,注意一下点和边的数量。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
typedef long long LL;
using namespace std;

const int MAXN = 4e4 + 5;
const int INF = 0x3f3f3f3f;
int head[MAXN], dist[MAXN], vis[MAXN], cur[MAXN];
int top = 0;

struct Edge {
    int to, cap, flow, next;
}edge[MAXN * 100];

void init() {
    top = 0;
    memset(head, -1, sizeof(head));
    memset(vis, 0, sizeof(vis));
}

void addedge(int a, int b, int c) {
    Edge E1 = {b, c, 0, head[a]};
    edge[top] = E1;
    head[a] = top++;
    Edge E2 = {a, 0, 0, head[b]};
    edge[top] = E2;
    head[b] = top++;
}

bool BFS(int st, int ed) {
    memset(dist, -1, sizeof(dist));
    memset(vis, 0, sizeof(vis));
    queue<int> que;
    que.push(st);
    vis[st] = 1;
    dist[st] = 0;
    while(!que.empty()) {
        int u = que.front();
        que.pop();
        for(int i = head[u]; i != -1; i = edge[i].next) {
            Edge E = edge[i];
            if(!vis[E.to] && E.cap > E.flow) {
                dist[E.to] = dist[u] + 1;
                vis[E.to] = 1;
                if(E.to == ed) return true;
                que.push(E.to);
            }
        }
    }
    return false;
}

int DFS(int x, int a, int ed) {
    if(x == ed || a == 0) return a;
    int flow = 0, f;
    for(int& i = cur[x]; i != -1; i = edge[i].next) {
        Edge& E = edge[i];
        if(dist[E.to] == dist[x] + 1 && (f = DFS(E.to, min(a, E.cap - E.flow), ed)) > 0) {
            E.flow += f;
            edge[i^1].flow -= f;
            flow += f;
            a -= f;
            if(a == 0) break;
        }
    }
    return flow;
}

int Maxflow(int st, int ed) {
    int flow = 0;
    while(BFS(st, ed)) {
        memcpy(cur, head, sizeof(head));
        flow += DFS(st, INF, ed);
    }
    return flow;
}

int main()
{
    init();
    int n, m;
    scanf("%d %d", &n, &m);
    int a, b, cos;
    for(int i = 1; i <= n; ++i) {
        scanf("%d %d", &a, &b);
        addedge(0, i, a);
        addedge(i, n + 1, b);
    }
    for(int i = 1; i <= m; ++i) { //这一步是核心
        scanf("%d %d %d", &a, &b, &cos);
        addedge(a, b, cos);
        addedge(b, a, cos);
    }
    printf("%d\n", Maxflow(0, n + 1));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36368339/article/details/80752712
今日推荐