解题报告 之 POJ3469 Dual Core CPU

解题报告 之 POJ3469 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 asAi 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: abw. 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

题目大意:有A、B两个CPU,有n个任务,m种数据传输。第 i 个任务在A上运行的代价为ai,B上运行的代价为bi,但它只需要选一个CPU运行即可。第 j 种数据传输是如果 任务aj 和任务bj不在同一CPU执行,则需要花费代价cj。问执行完所有任务的最小代价。

分析:用最小花费将点集分为两个子集的问题,可以转化为最小割问题,再转化为最大流。具体如下,超级源点连接每个任务 i,负载为ai。超级汇点连接每个任务i,负载为bi。对于数据传输,从aj连一条边到bj,负载为cj(双向)。然后求出最小割,即将点分为两个子集SA,SB的最小代价,也就是求改图的最大流。

不知道什么MAXN开到25000,MAXM开到500000也RTE。所以是醉了,开太大又给我超时,后来改进了一下模板才成功过掉,真是醉了,不过还是有收获的,至少把Dinic模板又优化了。总之这题的数据感觉很奇葩。

上代码:

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

const int MAXN = 201000;
const int MAXM = 2001000;
const int INF = 0x3f3f3f3f;

struct Edge
{
	int from, to, cap, next;
};

Edge edge[MAXM];
int level[MAXN];
int head[MAXN];
int src, des, cnt;

void addedge( int from, int to, int cap )
{
	edge[cnt].from = from;
	edge[cnt].to = to;
	edge[cnt].cap = cap;
	edge[cnt].next = head[from];
	head[from] = cnt++;

	swap( from, to );

	edge[cnt].from = from;
	edge[cnt].to = to;
	edge[cnt].cap = 0;
	edge[cnt].next = head[from];
	head[from] = cnt++;
}

int bfs( )
{
	memset( level, -1, sizeof level );
	queue<int> q;
	while(!q.empty( ))
		q.pop( );

	level[src] = 0;
	q.push( src );

	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].cap&&level[v] == -1)
			{
				level[v] = level[u] + 1;
				q.push( v );
			}
		}
	}
	return level[des] != -1;
}

int dfs( int u, int f )
{
	if(u == des)
		return f;
	int tem = 0;
	int res = 0;
	for(int i = head[u]; i != -1&&res<f; i = edge[i].next)
	{
		int v = edge[i].to;
		if(edge[i].cap > 0 && level[v] == level[u] + 1)
		{
			tem = dfs( v, min( f - res, edge[i].cap ) );
			edge[i].cap -= tem;
			edge[i ^ 1].cap += tem;
			res += tem;
		}
	}

	if(!res)
		level[u] = -1;
	return res;
}

int Dinic( )
{
	int ans = 0;
	while(bfs( ))
	{
		ans += dfs(src,INF);
	}
	return ans;
}

int main( )
{

	int n, m;
	src = 0;
	while(cin >> n >> m)
	{
		memset( head, -1, sizeof head );
		cnt = 0;
		des = n + 1;
		int a, b, c;

		for(int i = 1; i <= n; i++)
		{
			scanf( "%d%d", &a, &b );
			addedge( src, i, a );
			addedge( i, des, b );
		}

		for(int i = 1; i <= m; i++)
		{
			scanf( "%d%d%d", &a, &b, &c );
			addedge( a, b, c );
			addedge( b, a, c );
		}

		cout << Dinic( ) << endl;
	}

	return 0;
}

啦啦啦啦啦啦啦

时间: 2024-10-19 15:44:57

解题报告 之 POJ3469 Dual Core CPU的相关文章

poj3469 Dual Core CPU --- 最小割

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

POJ3469 Dual Core CPU(最小割)

形象生动的最小割.. 1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define INF (1<<30) 7 #define MAXN 2222 8 #define MAXM 888888 9 10 struct Edge{ 11 int v,cap,flow,next; 12 }ed

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 <cst

poj Dual Core CPU

Dual Core CPU 题目: 给出由核A和核B组成的双核CPU上的运行N个模块.模块i在核A上执行的花费为Ai,在核B上执行的花费为Bi.有M个互相之间需要进行数据交换的模块组合(ai,bi),如果,这两块模块在同一个核上执行则没有额外的费用,否则会产生wi的花费.请计算执行所有模块所需的最小花费. 算法分析: 用最小的费用将对象划分成两个集合问题,常常可以转换最小割后顺利解决. 这道题目就是这类问题的一个经典例子.考虑把N个模块按照在哪个核上运行分成两个集合. 然后,就是建图问题了.因为

Dual Core CPU (poj 3469 最小割求解)

Language: Default Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 19820   Accepted: 8601 Case Time Limit: 5000MS Description As more and more computers are equipped with dual core CPU, SetagLilb, the Chief Technology Offi

POJ 1637 Dual Core CPU 求最小割

据说这道题目是个很经典的题,好多人测最大流算法效率都是用的这题,只会dinic的弱菜第一法果断tle了,把vector改成数组了时候5s过. 下次什么时候学了isap在写一遍把 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostr

POJ 3469 Dual Core CPU

一堆任务分配到2个不同的芯片上运行,一个任务在不同芯片上运行的时间不一样,有一些任务组如果分配到不同的芯片上运行会产生额外的时间.... 用最小的费用将不同对象划分到两个集合 , 最小割问题 . 建图: 用源点汇点代表两个芯片 对某个任务 , 在 A 芯片上运行时间 t1 . 则从源点连一条 到 这个任务容量为 t1 的边 . 对 B 芯片上运行时间同理 如果两个任务间有联系,着再俩个任务间连边. 原问题就转化成了, 将图分成两部分,所切割的容量最少. 最小割==最大流 isap 解决 Dual

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 最大流dinic算法模板

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