POJ 3469 Dual Core CPU(最小割)

题目链接:Dual Core CPU

解题思路:这里有N个模式,运行在2个CPU上,每一个模式在每一个CPU上面运行的花费不同,而且部分模式间必须通信,如果都运行在一个CPU上面就不需要额外的耗费,否则需要额外的耗费W。求最小耗费的方法。

(1)—CPU1看做源点,CPU2看做汇点,将每一个模式连接源汇点,容量为题目给的花费。这样的话这个CPU的耗费只能是两个耗费中的最小着,应为不能超出容量。

(2)—再将需要通信的模式之间连接一条无向边,容量都为花费。如果这里的无向边没有流通过的话,说明他们在同一个CPU上面,如果有流通过但是没有满的话,说明选择了一个CPU中较大花费的模式,多余的流从这里走过,但是这样还是比在不同的CPU的花费小,如果正好满流量说明在不同的CPU之间。

(3)—说了这么多大家还是可以画一个图看看,比较直观,还有就是说这个是求最小割,其实最小割等于最大流。

#include<stdio.h>
#include<string.h>
#include<queue>
#define MAXV 300100
#define MAXE 600100
#define INF 0x3f3f3f3f

using namespace std;

struct Edge{
	int v, f, nxt;
};

int n, src, sink;
int g[MAXV];
int nume;
Edge e[MAXE];

void addedge(int u, int v, int c, int h){
	e[++nume].v = v;
	e[nume].f = c;
	e[nume].nxt = g[u];
	g[u] = nume;
	e[++nume].v = u;
	e[nume].f = h;
	e[nume].nxt = g[v];
	g[v] = nume;
}

void init(){
	memset(g, 0, sizeof(g));
	memset(e, 0, sizeof(e));
	nume = 1;
}

queue<int> que;
bool vis[MAXV];
int dist[MAXV];

void bfs(){
	memset(dist, 0, sizeof(dist));
	while(!que.empty())  que.pop();
	vis[src] = true;
	que.push(src);
	while(!que.empty()){
		int u = que.front();
		que.pop();
		for(int i = g[u]; i; i = e[i].nxt){
			if(e[i].f && !vis[e[i].v]){
				que.push(e[i].v);
				dist[e[i].v] = dist[u] + 1;
				vis[e[i].v] = true;
			}
		}
	}
}

int dfs(int u, int delta){
	if(u == sink){
		return delta;
	}
	else{
		int ret = 0;
		for(int i = g[u]; delta && i; i = e[i].nxt){
			if(e[i].f && dist[e[i].v] == dist[u] + 1){
				int dd = dfs(e[i].v, min(e[i].f, delta));
				e[i].f -= dd;
				e[i ^ 1].f += dd;
				delta -= dd;
				ret += dd;
			}
		}
		return ret;
	}
}

int maxflow(){
	int ret = 0;
	while(true){
		memset(vis, 0, sizeof(vis));
		bfs();
		if(!vis[sink])	return ret;
		ret += dfs(src, INF);
	}
}
//以上均为DINIC的模板
int main(){
	int i, j, k;
	int n, m;
	int a, b, c;
	while(scanf("%d%d", &n, &m) != EOF){
		init();
		src = 0;
		sink = n + 1;
		for(i = 1; i <= n; i++){
			scanf("%d%d", &a, &b);
			addedge(src, i, a, 0);
			addedge(i, sink, b, 0);
		}
		for(i = 0; i < m; i++){
			scanf("%d%d%d", &a, &b, &c);
			addedge(a, b, c, c);
		}
		printf("%d\n", maxflow());
	}
	return 0;
}

你可能感兴趣的:(POJ 3469 Dual Core CPU(最小割))