//Program HighestLablePreflowPush;HLPP

// 较快的网络流算法

//最高标号预留与推进算法

//记录d值,然后优先处理d值较高的,直至没有盈余。

// poj1459 Power Network

#include<cstdio>

#include<iostream>

#include<queue>

#include<algorithm>

#define maxn 105

#define max  210

using namespace std;

typedef struct node

{

int num;

int a[maxn];

}node;

int n,s,t,maxflow;

int map[maxn][maxn];        //边容量矩阵

int edge[maxn][maxn];       //邻接矩阵

int cur[maxn],d[maxn],e[maxn];

struct node list[2*maxn-1];

int flag;

void pagheuristic();

void insert(int level,int x)//加入标号为level的节点x

{    int num;

list[level].num++;

num = list[level].num;

list[level].a[num] = x;

}

void BFS()//精确计算距离标号dijkstra 建层次表

{

int p,q;int x[maxn];int i;

fill(d,d+maxn,max);

x[1] = t; d[t] = 0; q = 1; p = 0;

while(p<q)

{

p++;

for(i = 1; i <= edge[x[p]][0]; i++)

if(d[ edge[x[p]][i] ] == max){

q++;

x[q] = edge[x[p]][i];

d[x[q]] = d[x[p]] + 1;

if(x[q] != s) insert(d[x[q]],x[q]);

}

}

d[s] = n;

}

void push(int a,int b)

{

int x;

if(map[a][b] > e[a]) x = e[a];

else x = map[a][b];

map[a][b] -= x;

map[b][a] += x;

e[a] -= x;

e[b] += x;

}

void relabel(int a)

{

int i,min = max;

for(i = 1; i <= edge[a][0]; i++)

if(map[a][edge[a][i]] > 0 && d[edge[a][i]] < min)

min = d[edge[a][i]];

d[a] = min + 1;

if(flag++ % n == 0) pagheuristic(); //此处加优化

}

bool check(int a)//discharge

{    bool chk = false;

while(e[a] > 0)

{

if(cur[a] > edge[a][0]){

relabel(a); chk = true; cur[a] = 1;

}

else if(map[a][ edge[a][cur[a]] ] > 0 && d[a] == d[ edge[a][cur[a]] ] + 1)

push(a,edge[a][cur[a]]);//j = edge[a][cur[a]] -> b是a第j 个邻接点

else cur[a]++;

}

return chk;

}

void update(int level)//将所有标号在level上的点抛上九天,会不会就是pagheuristic

{

int j,k;

for(j = level+1; j <= n; j++){

for(k = 1; k <= list[j].num; k++){

list[n+1].a[list[n+1].num + k] = list[j].a[k];

d[list[j].a[k]] = n+1;

}

list[n+1].num += list[j].num;

list[j].num = 0;

}

}

void HLPP()

{

int i,b,level;

fill(e,e+maxn,0);

for(i = 1; i <= edge[s][0]; i++){//将所有s出发的弧充满

b = edge[s][i];

e[b] = map[s][b];

e[s] -= map[s][b];

map[b][s] = e[b];

map[s][b] = 0;

}

level = n;flag = 0;

while(level)

{

level--;

for(i = list[level].num; i >= 1; i--){

int a = list[level].a[i]; int num = list[level].num;

if(check(a)){                                                //如果有被重标记

if(level > 0 &&  list[level].num == 1) update(level);//免除把余流送回S的操作,该层只剩下一个点将要断层才可update,因为在层次图中如果断层,则断层上的顶点有留流,它必流回S,这时不用再计算,把它上放到n+1 层上去

insert(d[a],a);

list[level].a[i] = list[level].a[num];                  //有标记过则排除该点,把后面没标记的移到前面来

list[level].num--;

level = d[a];                                           //level 回升

break;                                                       //从新的最高level重新开始

}

}

}

}

int main()

{    void input(int node,int np,int nc,int m);

void init();

int node,np,nc,m;

while(scanf("%d%d%d%d",&node,&np,&nc,&m)==4)

{

input(node,np,nc,m);

init();

BFS();

HLPP();

maxflow = e[t];

printf("%d/n",maxflow);

}

return 0;

}

void init()

{

int i,j;

memset(edge,0,sizeof edge);

for(i = 0; i < n; i++)

for(j = i+1; j <= n; j++)

if(map[i][j]||map[j][i]){//建立邻接矩阵

edge[i][0]++;

edge[j][0]++;

edge[i][edge[i][0]] = j;

edge[j][edge[j][0]] = i;

}

fill(cur,cur+maxn,1);

for(i = 0; i <= n+1; i++) list[i].num = 0;

}

void input(int node,int np,int nc,int m)//complete map,mark s t n

{    int a,b,cap;int i;

n = node+1;

s = 0; t = node+1; maxflow = 0;

fill(map[0],map[maxn],0);

for (i = 0 ; i < m  ;i++)

{

while(getchar()!='(');

scanf("%d,%d)%d",&a,&b,&cap);

map[a+1][b+1] = cap;

}

for (i = 0 ; i < np ; i++)

{

while(getchar()!='(');

scanf("%d)%d",&b,&cap);

map[s][b+1] = cap;

}

for (i = 0 ; i < nc ; i++)

{

while(getchar()!='(');

scanf("%d)%d",&b,&cap);

map[b+1][t] = cap;

}

}

//距离标号法与重标记与前移算法容易退化,所以加一个优化pagheuristic——若存在某一个k(k<n),

//没有距离标号为k的点,则可以将标号为k--n的所有点移到标号为n+1,以此来提高效率。

//这个优化在relable时可以使用,为了节省时间,可以选在每k*n次检查一次。

void pagheuristic()

{

int count[maxn*2];

int i,j;

fill(count,count+2*maxn,0);

for(i = 1; i <= n; i++) count[d[i]]++;

j = 1;

while(j < n && count[j] != 0) j++;

if(j == n) return;

for(i = 1; i <= n; i++)

if(i != s && d[i] > j && d[i] <= n)

d[i] = n+1;

}

//http://billylinux.blog.hexun.com/16441424_d.html

//来自以上网址的翻译

最高标号预留与推进算法 --- 就是要比 Dinic 快!相关推荐

  1. 基于R语言的梯度推进算法介绍

    简介 通常来说,我们可以从两个方面来提高一个预测模型的准确性:完善特征工程(feature engineering)或是直接使用Boosting算法.通过大量数据科学竞赛的试炼,我们可以发现人们更钟爱 ...

  2. 百度上线惊雷算法3.0严打SEO快排作弊问题

    百度搜索重磅宣布,即将上线惊雷算法3.0,持续严打SEO快排作弊问题,这一波估计不少快排站又要消失了! 根据百度公开的惊雷算法3.0公告来看,这次算法就是针对SEO快排作弊来的,并且还给出了重点下手的 ...

  3. 最大流算法模板:EK和dinic算法

    最大流算法模板:EK和dinic算法 一.EK算法模板 #include<iostream> #include<queue> using namespace std; cons ...

  4. 共识算法解读-天下武功唯快不破Conflux共识算法

    共识算法解读-天下武功唯快不破Conflux共识算法 串行交易引发的吞吐量瓶颈 上次我们讲到GHOST算法,它在中本聪共识的基础上提出的确定主链的算法,在保障了在高吞吐量的同时还保障了安全性(即不容易 ...

  5. 【扔掉计算器】数学心算法《超棒超快》

    [扔掉计算器]数学心算法<超棒超快> 不推荐儿童或学生使用. 乘数的个位与被乘数相加,得数为前积,乘数的个位与被乘数的个位相乘,得数为后积,满十前一. 例:15×17 15 + 7 = 2 ...

  6. dijkstra标号法表格_Dijkstra算法详细讲解

    最短路径之 Dijkstra 算法详细讲解 1 最短路径算法 在日常生活中,我们如果需要常常往返 A 地区和 B 地区之间,我们最希望 知道的可能是从 A 地区到 B 地区间的众多路径中,那一条路径的 ...

  7. dijkstra标号法表格_dijkstra算法模板及其用法

    Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Di ...

  8. 【排序算法】——图解双轴快排(建议收藏)

    原创公众号:「bigsai」,转载需注明出处 关注回复bigsai领取Java进阶pdf,回复进群加入力扣打卡群(目前200+). 觉得不错还请一键三连! 前言 在排序算法中,快排是占比非常多的一环, ...

  9. 算法练习day5——190322(快排、建堆、调整堆)

    1.快速排序 1.1 非经典: 每次选取数组的最后一个元素为基准,进行排序: 将大于基准的排后边,小于基准的排前面,等于基准的在中间(类似于荷兰国旗问题): 直至进行排序的左边界=右边界. packa ...

最新文章

  1. 编写UEditor插件
  2. Quartus中常见错误·
  3. 百练OJ:2713:肿瘤面积
  4. Matlab Tricks(二十九) —— 使用 deal 将多个输入赋值给多个输出
  5. code blocks c语言,Code Blocks安装与使用图文教程(使用Code::Blocks编写C语言程序)...
  6. Latex: 表格中 自动换行居中
  7. 信息学奥赛一本通(1145:字符串p型编码)
  8. Vue - Nuxt.js 安装引入 WangEditor V5 富文本编辑器最新版本,超详细使用教程(Nuxt.js 项目使用官方提供的示例,页面报错,刷新就会报错navigator is解决方案)
  9. 用c语言写双人贪吃蛇,试图写了一个双人贪吃蛇,结果蛇竖着跑正常,横着跑就只有头了,求解~...
  10. 宝塔Linux面板 5.9专业版破解,付费插件安装免费使用,全网首发!
  11. linux终端清除命令,清除Linux终端的6个命令
  12. 小孩儿学计算机可以学些什么,基础知识
  13. 07、自己写库—构建库函数雏形
  14. Laravel Eloquent 必备的实用技巧
  15. ADC芯片CS1180的读取转换错误的情况记录
  16. 五大浏览器js 判断IE、Firefox、Safari、Chrome、Opera
  17. JAVA兴趣小组申请理由_关于参与兴趣小组申请书范文
  18. 74LS85 比较器 【数字电路】
  19. 为何亚马逊的中国电商之路以失败收场?当当网创始人这样说
  20. 【中兴交换机MC-LAG配置】

热门文章

  1. 这些机房布线规范你都知道吗
  2. 电池报废征兆,三招辨别该不该换新
  3. JAVA项目实训struts2_Java Web项目搭建过程记录(struts2)
  4. calibre中的hcell_关于calibre的Hcell你知道多少?
  5. 成功解决ImportError: Something is wrong with the numpy installation. While importing we detected an olde
  6. Interview:算法岗位面试—11.15下午上海某航天***公司(国企)技术面之工业机器视觉认知、计算机视觉算法的理解、目标检测相关项目案例
  7. DL之BP:利用乘法层/加法层(forward+backward)算法结合计算图(CG)求解反向求导应用题
  8. 数据标准化的方法与意义
  9. C#获取文件夹下指定格式的所有文件
  10. tomcat更改端口