当前位置: 代码迷 >> 综合 >> POJ 3469 Dual Core CPU(最小割,建图)
  详细解决方案

POJ 3469 Dual Core CPU(最小割,建图)

热度:31   发布时间:2023-12-13 19:12:34.0

最大流dinic算法,建图
题目意思:
双核计算机A,B,有n个模块,每个模块都要再CPU中运行,并且知道了每个模块在每个CPU上的运行时间,
如果它们运行在同一个cpu,就可以忽略共享数据的花费,否则需要额外的费用,求完成所有任务的最小花费;

本题要点:
1、最大流量=最小割容量
2、建图
建图:让两个CPU分别为图的源点s和汇点t,已知每个模块与两个CPU的运行时间Ai,Bi,则对于每个模块,
从s连向一条容量为Ai的边到这个模块,在从这个模块连一条容量为Bi的边到t;对于在不同模块运行的模块需要额外的花费w,
则在这两个模块之间连一条容量为w的双向边。
2、套用 dinic模板,计算最大流就是所求。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int MaxN = 20010, MaxM = 200010, inf = 0x3f3f3f3f;
int head[MaxN], ver[MaxM], Next[MaxM], edge[MaxM], d[MaxN];
int n, m, st, ed, tot, maxflow;
queue<int> q;void add(int x, int y, int z)
{
    ver[++tot] = y, edge[tot] = z, Next[tot] = head[x], head[x] = tot;ver[++tot] = x, edge[tot] = 0, Next[tot] = head[y], head[y] = tot;
}bool bfs()
{
    memset(d, 0, sizeof d);while(q.size())q.pop();q.push(st);	d[st] = 1;while(q.size()){
    int x = q.front();	q.pop();for(int i = head[x]; i; i = Next[i]){
    if(edge[i] && !d[ver[i]]){
    q.push(ver[i]);d[ver[i]] = d[x] + 1;if(ver[i] == ed)return 1;}}}return 0;
}int dinic(int x, int sum)
{
    if(x == ed)return sum;int max_flow = 0, k, i;for(i = head[x]; i; i = Next[i]){
    if(edge[i] && d[ver[i]] == d[x] + 1){
    k = dinic(ver[i], min(sum - max_flow, edge[i]));edge[i] -= k;edge[i ^ 1] += k;max_flow += k;if(max_flow == sum) return max_flow;}}if(!max_flow) d[x] = 0;return max_flow;
}int main()
{
    int a, b, val;while(~scanf("%d%d",&n,&m)){
    maxflow = 0, tot = 1;st = 0, ed = n + 1;memset(head, 0, sizeof head);memset(Next, 0, sizeof Next);for(int i = 1; i <= n; ++i){
    scanf("%d%d", &a, &b);add(st, i, a);add(i, ed, b);}for(int i = 0; i < m; ++i){
    scanf("%d%d%d", &a, &b, &val);add(a, b, val);add(b, a, val);}int flow = 0;while(bfs()){
    flow = dinic(st, inf);{
    maxflow += flow;}}printf("%d\n", maxflow);}return 0;
}/* 3 1 1 10 2 10 10 3 2 3 1000 *//* 13 */
  相关解决方案