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