不说别的,直接上模板。

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 模板的更多相关文章

  1. POJ 3469.Dual Core CPU 最大流dinic算法模板

    Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 24830   Accepted: 10756 ...

  2. (网络流 最大流 Dinic || SAP)Control -- hdu --4289

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=4289 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  3. 求最大流dinic算法模板

    //最短增广路,Dinic算法 struct Edge { int from,to,cap,flow; };//弧度 void AddEdge(int from,int to,int cap) //增 ...

  4. poj 1273最大流dinic算法模板

    #include<stdio.h> #include<string.h> #define N 300 #define inf 0x7fffffff #include<qu ...

  5. 最大流Dinic(模板)

    #define IOS ios_base::sync_with_stdio(0); cin.tie(0); #include <cstdio>//sprintf islower isupp ...

  6. 最大流Dinic算法模板(pascal)

    program rrr(input,output); const inf=; type pointer=^nodetype; nodetype=record t,c:longint; next,rev ...

  7. HDU1532最大流 Edmonds-Karp,Dinic算法 模板

    Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...

  8. hdu 4280 最大流 sap模板

    给你岛的坐标求最西边到最东边的最大流 /* 最大流模板 sap */ #include<stdio.h> #include<string.h> #include<algo ...

  9. POJ 1815 - Friendship - [拆点最大流求最小点割集][暴力枚举求升序割点] - [Dinic算法模板 - 邻接矩阵型]

    妖怪题目,做到现在:2017/8/19 - 1:41…… 不过想想还是值得的,至少邻接矩阵型的Dinic算法模板get√ 题目链接:http://poj.org/problem?id=1815 Tim ...

随机推荐

  1. Notes of the scrum meeting(10/28)

    meeting time:4:00~6:00p.m.,October 28th,2013 meeting place:雕刻时光 attendees: 顾育豪                       ...

  2. 怎么删除有外键约束的MySQL表中的数据

    SET FOREIGN_KEY_CHECKS = 0 操作结束后 SET FOREIGN_KEY_CHECKS = 1

  3. 【转】解析Java finally

    下文写的关于Java中的finally语句块什么时候执行的问题.什么时候执行呢?和return.continue.break.exit都有关系,尤其return语句非常有意思,于是分享给大家.谢谢Sm ...

  4. 3242: [Noi2013]快餐店 - BZOJ

    Description 小T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方. 快餐店的顾客分布在城 ...

  5. ORA-12505, TNS:listener does not currently know of SID given in connect descriptor

    引子: 本项目在老电脑上用的是oracle10g,换新电脑装的是oracle11g,但运行项目本没有什么关系,本来说创建个用户,用PLSQL手工导入数据,再改几下配置文件即可跑起来--但实际启动中遇到 ...

  6. Matlab实现求a到b被c整除的个数

    我先想到的是for循环........ 然后sum(find(mod(a:b,c)==0)),从10到100得到874,为什么不对呢? 比如a = [1 2 3 4  2 3 4 2],find(a= ...

  7. 不安装Oracle客户端远程连接Orcale数据库

    本方法是通过使用ORACLE官方提供的精简版客户端,即绿色免安装的客户端. 下载地址(此处提供的是官方各版本下载地址): Windows 32位系统中使用的客户端下载地址其他系统环境中使用的客户端下载 ...

  8. hdu 3807

    很好的思路     枚举有多少人有ipad 判是否满足题目给出的条件 #include <iostream> #include <cstring> #include <c ...

  9. httpsClient

    Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且 ...

  10. Eclipse对svn操作切换账号或更换svn地址方法

    1. 切换账号,主要是删除配置文件达到重新更新svn的时候,弹出框让重新输入新的svn用户名和密码. 1.通过删除SVN客户端的账号配置文件   1)查看你的Eclipse中使用的是什么SVN Int ...