最大流
来源:互联网 发布:linux配置ntp客户端 编辑:程序博客网 时间:2024/04/27 17:47
压入重标法Push-relabel algorithm(预流推进法Preflow-push method):
Push-relabel算法的流程如下:
1 )我们先假定一个高度函数 h ( u ) ,他代表u点的高度,只有h ( u )比较高的点才能够将水流到h ( u )比较低的点;
2 ) 在程序一开始的时候,让source node的高度是n ( node数) , 其它点的高度都是 0 ,这样source node才有足够的高度可以流往其它地方 ;
3 ) 然后, 让source node往其它所有跟他直接相邻的node ,都流水管宽度的水量 ( 流过去之后当然要计算剩下的网络情形,即计算 residual edges(残留网络)
4 )对所有active node( 目前有水的 node )做 relabel(重标记)的动作: 在当某个node明明有水,但是他所连出去的所有对象的 h ( u ) 都比
他还高, 则让他的h ( u ) 增加为至少有一条水管可以流出去的量,也就是让这个有水的 active node的高度变成比他连往的”高度最小的 n o d e ”+l , ( 流过去之后还是要计算剩下的网络情形
5 )对所有可以做push(压入)动作的node做push的动作。 所谓的Push动作是指 : 当某个node有水,并且他有可以流出去的边, 且他刚好比可以流出去的那个点高度高一点点 ( 高度恰好比他高 1 ) ,那就把某个node 的水流过去,要流多少呢?以下两者取 mi n。 A:流出去的水管的量( 也就是说,这个active node的水量很多, 足够把这条水管塞满( 饱和) ,这个时候就叫做saturating Push)(饱和压入);B:某个 n o d e 现在的水量( 这个 n o d e的水量不足以把流出去的这个水管填满,称作non saturating Push(不饱和压入)
6 )重复Relabel和Push的工作,一直到没有active node为止,此时从source node所流出的总流量( P r e f l o w) ,就是这个图的最大流量。
例子:
POJ1459
Description
A power network consists of nodes (power stations, consumers and dispatchers) connected by power transport lines. A node u may be supplied with an amount s(u) >= 0 of power, may produce an amount 0 <= p(u) <= pmax(u) of power, may consume an amount 0 <= c(u) <= min(s(u),cmax(u)) of power, and may deliver an amount d(u)=s(u)+p(u)-c(u) of power. The following restrictions apply: c(u)=0 for any power station, p(u)=0 for any consumer, and p(u)=c(u)=0 for any dispatcher. There is at most one power transport line (u,v) from a node u to a node v in the net; it transports an amount 0 <= l(u,v) <= lmax(u,v) of power delivered by u to v. Let Con=Σuc(u) be the power consumed in the net. The problem is to compute the maximum value of Con.An example is in figure 1. The label x/y of power station u shows that p(u)=x and pmax(u)=y. The label x/y of consumer u shows that c(u)=x and cmax(u)=y. The label x/y of power transport line (u,v) shows that l(u,v)=x and lmax(u,v)=y. The power consumed is Con=6. Notice that there are other possible states of the network but the value of Con cannot exceed 6.
Input
Output
Sample Input
2 1 1 2 (0,1)20 (1,0)10 (0)15 (1)207 2 3 13 (0,0)1 (0,1)2 (0,2)5 (1,0)1 (1,2)8 (2,3)1 (2,4)7 (3,5)2 (3,6)5 (4,2)7 (4,3)5 (4,5)1 (6,0)5 (0)5 (1)2 (3)2 (4)1 (5)4Sample Output
156#include<iostream>#include<stdio.h>#include<string.h>#define SIZE 202#define INF 0xfffffffusing namespace std;int map[SIZE][SIZE]; //保存图int f[SIZE][SIZE]; //记录边(u,v)的流量int e[SIZE]; //余流int h[SIZE]; //高度int n,nc,np,m;int source,sink;void push(int u,int v) //压入操作{ int d=min(e[u],map[u][v]-f[u][v]); //选取余流和残余流量的最小值 f[u][v]+=d; //更新流与余流 f[v][u]=-f[u][v];//反向流用于向上游回退盈余的e[u],以便从上游其它路流向终点 e[u]-=d; e[v]+=d;}bool relabel(int u){ int minh=INF,i; for(i=0;i<n+2;i++) if(map[u][i]>f[u][i]) minh=min(minh,h[i]); //当前流未超过容量 找到与u相邻的且高度最小的点 if(minh==INF) return false; //残留网络中无从u出发的路 h[u]=minh+1; //修改u的高度+1 for(i=0;i<n+2;i++) { if(e[u]==0) break; //无余流 不需再次压入 if(h[i]==minh&&map[u][i]>f[u][i]) //当高度与最小高度相等且流比容量小时进行push操作 push(u,i); } return true;}void init_preflow(){ int i; memset(h,0,sizeof(h)); memset(e,0,sizeof(e)); h[source]=n+2; //h[sink]=0;可省略 for(i=0;i<n+2;i++) { if(map[source][i]==0) continue; f[source][i]=map[source][i]; f[i][source]=-f[source][i]; e[i]=map[source][i]; e[source]=-map[source][i]; }}void push_relabel(){ init_preflow(); //初始化 bool flag=true; //表示是否还能进行relabel操作 int i; while(flag) //还可以进行重标记操作 { flag=false; for(i=0;i<n;i++) if(e[i]>0) flag=flag||relabel(i); }}int main(){ int i; int x,y,value; while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF) { memset(map,0,sizeof(map)); memset(f,0,sizeof(f)); source=n; sink=n+1;//增加超级源点和超级汇点 while(m--) { scanf(" (%d,%d)%d",&x,&y,&value); map[x][y]=value; } for(i=0;i<np;i++) { scanf(" (%d)%d",&x,&value); map[source][x]=value; } for(i=0;i<nc;i++) { scanf(" (%d)%d",&x,&value); map[x][sink]=value; } push_relabel(); printf("%d\n",e[sink]); } return 0;}
- 最大流-最大利益
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- 最大流
- java个人学习笔记19(多生产者多消费者+循环判断标记+notifyAll()+Lock+Condition)
- JS实现加密解密(转)
- 修改状态栏字体颜色
- Ubuntu基本目录结构 Ubuntu Linux基本目录 目 录 名 描 述 /
- requestCode 和 resultCode .
- 最大流
- 【cocos2d-x制作别踩白块儿】第五期:添加普通黑白块行
- 程序员面试智力题 (4)
- webstorm添加jQurey和EXT提示
- 图搜索(广度优先java)
- vs2012(visual studio)关闭拼写检查方法
- 尝试用Gearman实现分布式处理(PHP)
- 图的深度优先遍历和广度优先遍历
- 设计模式C++实现(2)——策略模式