POJ_3469 Dual Core CPU 最大流
来源:互联网 发布:酒店智能门锁 网络 编辑:程序博客网 时间:2024/06/05 10:15
http://poj.org/problem?id=3469
题意:
有N项工作需要用CPU执行完成,现在只有2个CPU,已知每个项任务在两个CPU上
的执行时间,并且还给出了一些约束条件,每个约束条件是:(u , v , c)表示如果任务
u和v不在同一个机器上执行的话,就需要付出额外的c的代价,求完全任务的最少花
费是多少。
思路:
首先每项任务都需要完成,而且每项任务都只能在一台机器上完成,这不免会让人想
到是否可以用2-sat,但是问题是题目中并没有给没有给出两个不能在同一台机器上,
而是给出了两个任务不在同一台机器上的代价,没有“冲突”,因此我们不能用2-sat解决。
然后就是考虑到每个任务只要在A机器或是B机器上完成,也就是说我们只需要确定一种
方案将所有任务分别分在A或是B上就可以了,这样我们就会想到最大流最小割定理,可
以利用求最大流来求出图的最小割,从而求解本题。建图的原则是,引入一个超级源点
和超级汇点,从源点引一条边到每个点,代价为该点在机器A上执行的时间,从每个点引
一条边到汇点,代价为该点在机器B上执行的时间,对于题目中给出的约束(u , v ,c )添加
一条总u到v的代价为c的边和 v到u的代价为c的边,最后跑一次最大流的sap算法就可以出解。
代码:
#include<stdio.h>#include<string.h>#define MIN(a,b) (a)>(b)?(b):(a)#define CC(m ,what) memset(m , (what) , sizeof(m))#define FF(i , CH) for(int i=0;i<CH;i++)int N ,M ,S,T;const int MAX_E = 600000 ;const int MAXN = 20020 ;const int inf = (1<<30) ;struct Node{ int num ,dis ,next;}p[MAX_E*2] ;int root[MAXN] ,cnt,nodenum;void init(){ memset(root, -1 , sizeof(root)); cnt = 0 ; S = 0 ; T = N + 1 ;}void add(int a , int b , int c ,int cc=0){ p[cnt].num = b ; p[cnt].dis = c ; p[cnt].next = root[a] ; root[a] = cnt++ ; p[cnt].num = a ; p[cnt].dis = cc ; p[cnt].next = root[b] ; root[b] = cnt++ ;}int dis[MAXN] , gap[MAXN] , cur[MAXN] , pre[MAXN];/*用领接矩阵实现的SAPdis[i]: 层次图中点i到T的距离cur[i]: i结点当前出去的边的编号pre[i]: i结点的前一个结点*/void checkmin(int &a , int b){ a = a > b ? b : a ;}void sap(){ CC(dis, 0); CC(gap , 0) ; FF(i , nodenum) cur[i] = root[i] ; int u = pre[S] = S ,max_flow = 0 , aug = inf ; gap[0] = nodenum ; while( dis[S] < nodenum){loop : for(int &i=cur[u] ;i!=-1;i=p[i].next){ int v = p[i].num ; if( p[i].dis && dis[u] == dis[v] + 1){ checkmin( aug , p[i].dis ) ; pre[ v ] = u ; u = v ; if(v == T){ max_flow += aug ; for(u = pre[u] ; v != S ; v=u,u=pre[u]){ p[ cur[u] ].dis -= aug ; p[ cur[u]^1 ].dis += aug ; } aug = inf ; } goto loop ; } } int mind = nodenum ; for(int i=root[u] ;i!=-1;i=p[i].next){ int v = p[i].num ; if( p[i].dis && mind > dis[v] ){ mind = dis[v] ; cur[u] = i ; } } if( (--gap[ dis[u] ])==0) break ; gap[ dis[u] = mind + 1 ]++ ; u = pre[u] ; } printf("%d\n",max_flow) ;}int main(){ int a, b ,c; while(scanf("%d%d",&N,&M) == 2){ init() ; for(int i=1;i<=N;i++){ scanf("%d%d",&a,&b); add(S,i,a); add(i,T,b); } for(int i=1;i<=M;i++){ scanf("%d%d%d",&a,&b,&c); add(a,b,c,c) ; } nodenum = N + 2 ; sap() ; } return 0;}
- POJ_3469 Dual Core CPU 最大流
- POJ3469 Dual Core CPU 最大流dinic
- poj 3469 Dual Core CPU (最大流)
- poj 3469 Dual Core CPU (最小割->最大流)
- POJ 3469 Dual Core CPU---dinic求最大流
- POJ 3469 - Dual Core CPU(Dinic最大流)
- POJ 3469 Dual Core CPU 最大流最小割
- POJ -- 3469 Dual Core CPU (最大流,最小割)
- poj 3469 Dual Core CPU 最大流最小割定理
- poj 3469 Dual Core CPU (最小割最大流)
- poj 3469 Dual Core CPU 最大流-最小割
- POJ3469 Dual Core CPU(最大流最小割定理)
- 最大流-最小割定理&poj3469 Dual Core CPU
- POJ 3469 Dual Core CPU <Dinic + 最小割 + 最大流>
- Poj 3469 Dual Core CPU【最小割最大流-----Dinic】
- POJ 3469->Dual Core CPU(最大流最小割问题)
- poj 3469 Dual Core CPU(最小费用最大流)
- poj3469 Dual Core CPU-最小花费-最大流最小割
- 5-17
- 阻塞与死锁(二)——各种操作对锁的申请
- gdb
- android开发基础知识(3) ---五大布局
- shell 编程之2>&1
- POJ_3469 Dual Core CPU 最大流
- 把数据库中的datatime类型字段 用字符串的形式输出(如05-20-2012)
- 使用enable_shared_from_this
- Android开发实例详解之IMF
- ubuntu 11.10 install QQ
- LINUX下安装 ACE
- 将字符串右边的空白去掉
- c++文件流的复制操作
- [转]Linux2.6内核中基于platform机制的驱动模型