POJ 3469 Dual Core CPU(最小割)

POJ 3469 Dual Core CPU

题目链接

题意:有a,b两台机器,有n个任务,在a机器和b机器需要不同时间,给定m个限制,如果u, v在不同机器需要额外开销,问最小开销

思路:最小割,源点为a机器,汇点为b机器,这样的话求出最小割,就是把点分成两个集合的最小代价,然后如果u, v在不同机器需要开销,则连u,v v,u两条边,容量为额外开销,这样如果这条边是割边,则a,b会在不同集合,并且代价就会被加上去

代码:

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

const int MAXNODE = 20005;
const int MAXEDGE = 1000005;

typedef int Type;
const Type INF = 0x3f3f3f3f;

struct Edge {
	int u, v;
	Type cap, flow;
	Edge() {}
	Edge(int u, int v, Type cap, Type flow) {
		this->u = u;
		this->v = v;
		this->cap = cap;
		this->flow = flow;
	}
};

struct Dinic {
	int n, m, s, t;
	Edge edges[MAXEDGE];
	int first[MAXNODE];
	int next[MAXEDGE];
	bool vis[MAXNODE];
	Type d[MAXNODE];
	int cur[MAXNODE];
	vector<int> cut;

	void init(int n) {
		this->n = n;
		memset(first, -1, sizeof(first));
		m = 0;
	}
	void add_Edge(int u, int v, Type cap) {
		edges[m] = Edge(u, v, cap, 0);
		next[m] = first[u];
		first[u] = m++;
		edges[m] = Edge(v, u, 0, 0);
		next[m] = first[v];
		first[v] = m++;
	}

	bool bfs() {
		memset(vis, false, sizeof(vis));
		queue<int> Q;
		Q.push(s);
		d[s] = 0;
		vis[s] = true;
		while (!Q.empty()) {
			int u = Q.front(); Q.pop();
			for (int i = first[u]; i != -1; i = next[i]) {
				Edge& e = edges[i];
				if (!vis[e.v] && e.cap > e.flow) {
					vis[e.v] = true;
					d[e.v] = d[u] + 1;
					Q.push(e.v);
				}
			}
		}
		return vis[t];
	}

	Type dfs(int u, Type a) {
		if (u == t || a == 0) return a;
		Type flow = 0, f;
		for (int &i = cur[u]; i != -1; i = next[i]) {
			Edge& e = edges[i];
			if (d[u] + 1 == d[e.v] && (f = dfs(e.v, min(a, e.cap - e.flow))) > 0) {
				e.flow += f;
				edges[i^1].flow -= f;
				flow += f;
				a -= f;
				if (a == 0) break;
			}
		}
		return flow;
	}

	Type Maxflow(int s, int t) {
		this->s = s; this->t = t;
		Type flow = 0;
		while (bfs()) {
			for (int i = 0; i < n; i++)
				cur[i] = first[i];
			flow += dfs(s, INF);
		}
		return flow;
	}

	void MinCut() {
		cut.clear();
		for (int i = 0; i < m; i += 2) {
			if (vis[edges[i].u] && !vis[edges[i].v])
				cut.push_back(i);
		}
	}
} gao;

int n, m;

int main() {
	while (~scanf("%d%d", &n, &m)) {
		gao.init(n + 2);
		int a, b, w;
		for (int i = 1; i <= n; i++) {
			scanf("%d%d", &a, &b);
			gao.add_Edge(0, i, a);
			gao.add_Edge(i, n + 1, b);
		}
		while (m--) {
			scanf("%d%d%d", &a, &b, &w);
			gao.add_Edge(a, b, w);
			gao.add_Edge(b, a, w);
		}
		printf("%d\n", gao.Maxflow(0, n + 1));
	}
	return 0;
}
时间: 2024-10-23 18:17:10

POJ 3469 Dual Core CPU(最小割)的相关文章

poj 3469 Dual Core CPU 最小割

题意: 有n个模块在A和B核组成的双核计算机上运行,各个模块在A,B核上的运行时间已知,另外有m个三元组(a,b,w),表示a模块和b模块如果不在一个核上运行要产生w的额外花销,求总的最小花销. 分析: 即把n个模块划分为两个集合,可用求最小割的方法解决. 代码: //poj 3469 //sep9 #include <iostream> #include <queue> #include <algorithm> using namespace std; const i

poj 3469 Dual Core CPU——最小割

题目:http://poj.org/problem?id=3469 最小割裸题. 那个限制就是在 i.j 之间连双向边. 根据本题能引出网络流中二元关系的种种. 别忘了写 if ( x==n+1 ) return flow ; ! #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=2e4+5,M=2e5+

【网络流#8】POJ 3469 Dual Core CPU 最小割 - 《挑战程序设计竞赛》例题

[题意]有n个程序,分别在两个内核中运行,程序i在内核A上运行代价为ai,在内核B上运行的代价为bi,现在有程序间数据交换,如果两个程序在同一核上运行,则不产生额外代价,在不同核上运行则产生Cij的额外代价,问如何划分使得代价最小. 用最小的费用将对象划分为两个集合的问题,常常可以转换为最小割后顺利解决 建立源点与汇点,每个程序视为一个点,源点与在各个程序连一条边,最大流量为bi,汇点与各个程序连一条边,最大流量ai,对于有额外代价的程序,连一条双向边,流量为cij. 一开始用Dinic算法做,

poj 3469 Dual Core CPU 最大流最小割定理

#include<stdio.h> #include<string.h> #include<queue> #include<vector> using namespace std; const int N=200000+5; const int inf=1<<24; struct Edge { int from,to,cap,flow; }; vector<Edge>edges; vector<int>G[N]; int

POJ 3469 Dual Core CPU (求最小割)

POJ 3469 Dual Core CPU 链接:http://poj.org/problem?id=3469 题意:有两个cpu,n个模块.每个模块运行在连个cpu上运行时间不同.有m对模块之间要进行信息交互,如果模块在同一个cpu,那么进行信息交互时不需要额外时间,否则要花额外的时间.问怎么样分配模块,能够使得花费的时间最少. 思路:要将模块分给两个cpu,同时要使得时间最少,其实就是求最小割.那么题目可以转化为求最大流. 代码: /* ID: [email protected] PROG

POJ 3469 Dual Core CPU(网络流之最小割)

题目地址:POJ 3469 建图思路:建源点与汇点,源点与CPU1相连,汇点与CPU2相连,对共享数据的之间连无向边. 我的ISAP过这题还是毫无时间压力的嘛... 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctyp

POJ 3469 Dual Core CPU 最大流

划分成两个集合使费用最小,可以转成最小割,既最大流. //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<sstream> #include<cm

poj3469 Dual Core CPU --- 最小割

一个CPU有两个核,要把n个模块放在其中一个核上,给出放在不同核上的花费. 另给出m对模块,若不放在同一模块则会产生额外花费.求最小花费. 对于每一个模块可以选择核1,核2,和相连的模块. 据此建边,核1为源点,核2为汇点,相连的模块之间建双向边,边权均为花费.求最小割即可. #include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmat

POJ 3469 --Dual Core CPU【最小割】

Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 20852   Accepted: 9010 Case Time Limit: 5000MS Description As more and more computers are equipped with dual core CPU, SetagLilb, the Chief Technology Officer of TinySoft Co