最大流 Dinic + Sap 模板
不说别的,直接上模板。
Dinic+当前弧优化:
struct Edge{
int x,y,c,ne;
}e[M*];
int be[N],all;
int d[N],q[N];
int stack[N],top;//栈存的是边
int cur[N];//当前弧优化
void add(int x, int y, int z)//需保证相反边第一个为偶数
{
e[all].x=x; e[all].y=y; e[all].c=z;
e[all].ne=be[x];
be[x]=all++;
e[all].x=y; e[all].y=x; e[all].c=;
e[all].ne=be[y];
be[y]=all++;
}
bool BFS(int s, int t)//化为层次图 使得边数从m降低为n 复杂度随之下降
{
memset(d,-,sizeof(d));
int head=,tail=;
q[++tail]=s;
d[s]=;
while(head!=tail)
{
int u=q[++head];
for(int i=be[u]; i!=-; i=e[i].ne)
if(e[i].c> && d[e[i].y]==-){
d[e[i].y]=d[u]+;
q[++tail]=e[i].y;
if(tail==N-) tail=;
if(e[i].y==t) return ;
}
}
return ;
}
int Dinic(int s, int t)//防止爆栈 用stack模拟递归
{
int ans=;
while(BFS(s,t))
{
memcpy(cur,be,sizeof(be));
int u=s;
top=;//dfs开始 清空栈
while()
{
if(u==t)
{
int minc=,mini;
for(int i=; i<top; i++)
if(minc>e[stack[i]].c)
{
minc=e[stack[i]].c;
mini=i;//以便之后回到这继续增广
}
for(int i=; i<top; i++)
{
e[stack[i]].c-=minc;
e[stack[i]^].c+=minc;//第一个二进制取反 即取相反边
}
ans+=minc;
top=mini;
u=e[stack[mini]].x;
}
for(int i=cur[u]; i!=-; cur[u]=i=e[cur[u]].ne)
if(e[i].c> && d[e[i].y]==d[e[i].x]+) break;
if(cur[u]!=-)
{
stack[top++]=cur[u];
u=e[cur[u]].y;
}else
{
if(top==) break; //循环结束标志
d[u]=-;//当前节点不在增广路中 删除
u=e[stack[--top]].x;//回溯
}
}
}
return ans;
}
ISAP+GAP+当前弧优化:
struct Edge{
int x,y,c,ne;
}e[M*];
int x,y,z,n,m,s,t;
int be[N],all;
int d[N],q[N];
int stack[N];//模拟递归
int gap[N],cur[N];//gap优化+当前弧优化
void add(int x, int y, int z)//保证第一个为偶数
{
e[all].x=x; e[all].y=y; e[all].c=z;
e[all].ne=be[x];
be[x]=all++;
e[all].x=y; e[all].y=x; e[all].c=;
e[all].ne=be[y];
be[y]=all++;
}
void BFS(int s, int t)
{
memset(d,-,sizeof(d));
memset(gap,,sizeof(gap));
gap[]=;
int head=,tail=;
q[++tail]=t;
d[t]=;
while(head!=tail)
{
int u=q[++head];
for(int i=be[u]; i!=-; i=e[i].ne)
if(d[e[i].y]==-)
{
d[e[i].y]=d[u]+;
q[++tail]=e[i].y;
gap[d[e[i].y]]++;
}
}
}
int sap(int s, int t, int n)
{
int ans=;
BFS(s,t);
memcpy(cur,be,sizeof(be));
int top=;
int u=s;
while(d[s]<n)
{
if(u==t)
{
int minc=,mini;
for(int i=; i<top; i++)
if(minc>e[stack[i]].c)
{
minc=e[stack[i]].c;
mini=i;
}
for(int i=; i<top; i++)
{
e[stack[i]].c-=minc;
e[stack[i]^].c+=minc;
}
ans+=minc;
top=mini;
u=e[stack[mini]].x;
continue;
}
for(int i=cur[u]; i!=-; cur[u]=i=e[i].ne)//当前弧优化
if(e[i].c> && d[e[i].y]+==d[u]) break;
if(cur[u]!=-)
{
stack[top++]=cur[u];
u=e[cur[u]].y;
}else
{
int mind=n;
for(int i=be[u]; i!=-; i=e[i].ne)//更新距离标号
if(e[i].c> && mind>d[e[i].y])
{
mind=d[e[i].y];
cur[u]=i;
}
gap[d[u]]--;
if(!gap[d[u]]) return ans;//gap表示当前距离的点有多少个 一旦==0 说明断层直接退出循环
d[u]=mind+;
gap[d[u]]++;
if(u!=s) u=e[stack[--top]].x;
}
}
return ans;
}
void init()
{
all=;
memset(be,-,sizeof(be));
}
最大流 Dinic + Sap 模板的更多相关文章
- POJ 3469.Dual Core CPU 最大流dinic算法模板
Dual Core CPU Time Limit: 15000MS Memory Limit: 131072K Total Submissions: 24830 Accepted: 10756 ...
- (网络流 最大流 Dinic || SAP)Control -- hdu --4289
链接: http://acm.hdu.edu.cn/showproblem.php?pid=4289 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- 求最大流dinic算法模板
//最短增广路,Dinic算法 struct Edge { int from,to,cap,flow; };//弧度 void AddEdge(int from,int to,int cap) //增 ...
- poj 1273最大流dinic算法模板
#include<stdio.h> #include<string.h> #define N 300 #define inf 0x7fffffff #include<qu ...
- 最大流Dinic(模板)
#define IOS ios_base::sync_with_stdio(0); cin.tie(0); #include <cstdio>//sprintf islower isupp ...
- 最大流Dinic算法模板(pascal)
program rrr(input,output); const inf=; type pointer=^nodetype; nodetype=record t,c:longint; next,rev ...
- HDU1532最大流 Edmonds-Karp,Dinic算法 模板
Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- hdu 4280 最大流 sap模板
给你岛的坐标求最西边到最东边的最大流 /* 最大流模板 sap */ #include<stdio.h> #include<string.h> #include<algo ...
- POJ 1815 - Friendship - [拆点最大流求最小点割集][暴力枚举求升序割点] - [Dinic算法模板 - 邻接矩阵型]
妖怪题目,做到现在:2017/8/19 - 1:41…… 不过想想还是值得的,至少邻接矩阵型的Dinic算法模板get√ 题目链接:http://poj.org/problem?id=1815 Tim ...
随机推荐
- android 中使用回调方法(适用于自定义view传值到activity、adapter传值到activity)
如图所示: 每当listview中有选中的操作时都需要发消息给activity,用来实时改变真实需要支付的剩余金额. 代码暂不公开啦!公司项目!
- Enterprise Library 6——Using the Logging Application Block
原文参考 http://msdn.microsoft.com/en-us/library/dn440731(v=pandp.60).aspx 一.简介 .更重要的是用于审计.这种日志可以跟踪用户的行为 ...
- shell脚本积累
统计当前目录下文件夹的大小 for d in $(ls) do du -sh ./$d done 获取之前日期date +"%Y%m%d" -d "-n days&q ...
- HDU 4587 TWO NODES 割点
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4587 题意: 删除两个点,使连通块的数目最大化 题解: 枚举删除第一个点,然后对删除了第一个点的图跑 ...
- Log4j XML配置
问题描述: Log4j XML配置 问题解决: (1)编写log4j.xml配置文件 注: 如上的XML文件必须以log4j.xml文件命名,否则无法读取配置文件,同样的如果 ...
- 剑指offer--面试题5
到现在为止,看过的书+代码有一定量了,并且也参加了个比赛,给自己的总体感觉:编程需要的是灵活的头脑,书里的东西只是讲个规则.思想,其实际实现可以千差万别! 潜在的规则+灵活的思维 = 程序! 在做 ...
- java web项目 。classpath 文件解析
eclipse工程中.classpath文件含义: 下面是一个.classpath文件内容: < ?xml version="1.0" encoding="UTF- ...
- HDU 1385 Minimum Transport Cost (最短路,并输出路径)
题意:给你n个城市,一些城市之间会有一些道路,有边权.并且每个城市都会有一些费用. 然后你一些起点和终点,问你从起点到终点最少需要多少路途. 除了起点和终点,最短路的图中的每个城市的费用都要加上. 思 ...
- ifram一些常用的知识点
本文摘自:http://www.cnblogs.com/duankaige/archive/2012/09/20/2695012.html iframe的调用包括以下几个方面:(调用包含html ...
- HDU 1882 Strange Billboard(位运算)
题目链接 题意 : 给你一个矩阵,有黑有白,翻转一个块可以让上下左右都翻转过来,问最少翻转多少次能让矩阵变为全白. 思路 : 我们从第一行开始枚举要翻转的状态,最多可以枚举到2的16次方,因为你只要第 ...