最大流dinic模板
循环版,点的编号从0开始:
const int MAXN = ;
const int MAXM = ;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to, next, cap, flow;
}edge[MAXM];
int tol;
int head[MAXN];
void init()
{
tol = ;
memset(head, -, sizeof(head));
}
void addedge(int u, int v, int w, int rw=)
{
edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = ;
edge[tol].next = head[u]; head[u] = tol++;
edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = ; //存反向边
edge[tol].next = head[v]; head[v] = tol++;
}
int Q[MAXN];
int dep[MAXN], cur[MAXN], sta[MAXN];
bool bfs(int s, int t, int n)
{
int front = , tail = ;
memset(dep, -, sizeof(dep[])*(n+));
dep[s] = ;
Q[tail++] = s;
while(front < tail)
{
int u = Q[front++];
for(int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap > edge[i].flow && dep[v] == -)
{
dep[v] = dep[u] + ;
if(v == t) return true;
Q[tail++] = v;
}
}
}
return false;
}
int dinic(int s, int t, int n) { //s是源点编号,t是汇点编号,n是点的总数,返回最大流
int maxflow = ;
while(bfs(s, t, n)) {
for(int i = ; i < n; i++) cur[i] = head[i];
int u = s, tail = ;
while(cur[s] != -)
{
if(u == t)
{
int tp = INF;
for(int i = tail-; i >= ; i--)
tp = min(tp, edge[sta[i]].cap-edge[sta[i]].flow);
maxflow+=tp;
for(int i = tail-; i >= ; i--) {
edge[sta[i]].flow+=tp;
edge[sta[i]^].flow-=tp;
if(edge[sta[i]].cap-edge[sta[i]].flow==)
tail = i;
}
u = edge[sta[tail]^].to;
}
else
if(cur[u] != - && edge[cur[u]].cap > edge[cur[u]].flow && dep[u] + == dep[edge[cur[u]].to])
{
sta[tail++] = cur[u];
u = edge[cur[u]].to;
}
else
{
while(u != s && cur[u] == -)
u = edge[sta[--tail]^].to;
cur[u] = edge[cur[u]].next;
}
}
}
return maxflow;
}
dfs增广路版,点的编号从0开始:
const int MAXN = ;
const int MAXM = ;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to, next, cap, flow;
}edge[MAXM];
int tol;
int head[MAXN];
void init()
{
tol = ;
memset(head, -, sizeof(head));
}
void addedge(int u, int v, int w, int rw=)
{
edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = ;
edge[tol].next = head[u]; head[u] = tol++;
edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = ; //存反向边
edge[tol].next = head[v]; head[v] = tol++;
}
int Q[MAXN];
int dep[MAXN], cur[MAXN], sta[MAXN];
bool bfs(int s, int t, int n)
{
int front = , tail = ;
memset(dep, -, sizeof(dep[])*(n+));
dep[s] = ;
Q[tail++] = s;
while(front < tail)
{
int u = Q[front++];
for(int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap > edge[i].flow && dep[v] == -)
{
dep[v] = dep[u] + ;
if(v == t) return true;
Q[tail++] = v;
}
}
}
return false;
} int dfs(int u,int t,int f) //dfs寻找增广路
{
if(u==t) return f;
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].cap > edge[i].flow && dep[v]==dep[u]+)
{
int d=dfs(v,t,min(f,edge[i].cap-edge[i].flow));
if(d>)
{
edge[i].flow+=d;
edge[i^].flow-=d;
return d;
}
}
}
return ;
} int dinic(int s, int t, int n) { //s是源点编号,t是汇点编号,n是点的总数,返回最大流
int maxflow = , f;
while(bfs(s, t, n))
{
while(f=dfs(s,t,INF))
maxflow+=f;
}
return maxflow;
}
不建反向边(一般用不到),点的编号从0开始:
const int MAXN = ;
const int MAXM = ;
const int INF = 0x3f3f3f3f;
struct Edge
{
int from,to, next, cap, flow;
}edge[MAXM];
int tol;
int head[MAXN];
void init()
{
tol = ;
memset(head, -, sizeof(head));
}
int min(int a,int b)
{
return a>b?b:a;
}
void addedge(int u, int v, int w, int rw=)
{
edge[tol].from=u; //记录起点
edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = ;
edge[tol].next = head[u]; head[u] = tol++;
}
int Q[MAXN];
int dep[MAXN], cur[MAXN], sta[MAXN];
bool bfs(int s, int t, int n)
{
int front = , tail = ;
memset(dep, -, sizeof(dep[])*(n+));
dep[s] = ;
Q[tail++] = s;
while(front < tail)
{
int u = Q[front++];
for(int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap > edge[i].flow && dep[v] == -)
{
dep[v] = dep[u] + ;
if(v == t) return true;
Q[tail++] = v;
}
}
}
return false;
}
int dinic(int s, int t, int n) { //s是源点编号,t是汇点编号,n是点的总数,返回最大流
int maxflow = ;
while(bfs(s, t, n)) {
for(int i = ; i < n; i++) cur[i] = head[i];
int u = s, tail = ;
while(cur[s] != -)
{
if(u == t)
{
int tp = INF;
for(int i = tail-; i >= ; i--)
tp = min(tp, edge[sta[i]].cap-edge[sta[i]].flow);
maxflow+=tp;
for(int i = tail-; i >= ; i--) {
edge[sta[i]].flow+=tp;
edge[sta[i]^].flow-=tp;
if(edge[sta[i]].cap-edge[sta[i]].flow==)
tail = i;
}
u = edge[sta[tail]].from;
}
else
if(cur[u] != - && edge[cur[u]].cap > edge[cur[u]].flow && dep[u] + == dep[edge[cur[u]].to])
{
sta[tail++] = cur[u];
u = edge[cur[u]].to;
}
else
{
while(u != s && cur[u] == -)
u = edge[sta[--tail]].from;
cur[u] = edge[cur[u]].next;
}
}
}
return maxflow;
}
最大流dinic模板的更多相关文章
- 网络流--最大流dinic模板
标准的大白书式模板,除了变量名并不一样……在主函数中只需要用到 init 函数.add 函数以及 mf 函数 #include<stdio.h> //差不多要加这么些头文件 #includ ...
- 网络流-最大流 Dinic模板
#include <bits/stdc++.h> using namespace std; #define MP make_pair #define PB push_back #defin ...
- hdu-4289 最大流Dinic模板题
拆点,套模板. 详情见代码. // // main.cpp // hdu_4289 // // Created by Luke on 16/8/29. // Copyright © 2016年 Luk ...
- POJ 1273 Drainage Ditches(最大流Dinic 模板)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n, ...
- 网络流--最大流--Dinic模板矩阵版(当前弧优化+非当前弧优化)
//非当前弧优化版 #include <iostream> #include <cstdio> #include <math.h> #include <cst ...
- 【最大流Dinic模板】HDU1532&POJ1273-Drainage Ditches(16/3/6更正)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #inc ...
- 网络最大流dinic模板
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using ...
- 最大流算法 ISAP 模板 和 Dinic模板
ISAP // UVa11248 Frequency Hopping:使用ISAP算法,加优化 // Rujia Liu struct Edge { int from, to, cap, flow; ...
- 洛谷P3376【模板】网络最大流 Dinic模板
之前的Dinic模板照着刘汝佳写的vector然后十分鬼畜跑得奇慢无比,虽然别人这样写也没慢多少但是自己的就是令人捉急. 改成邻接表之后快了三倍,虽然还是比较慢但是自己比较满意了.虽然一开始ecnt从 ...
随机推荐
- 1、微信小程序----弹幕的实现(无后台)
小程序刚刚出来,现在网上的demo是多,但是要找到一个自己需要的却不容易.今天跟大家分享自己写的一个弹幕功能. 先来一张效果图: 我的思路是这样的,先用<switch>标签确定是否打开弹幕 ...
- OC中单例的使用
单例:一个类只能创建一个实例,保证在全局使用过程中是唯一的实例,方便统一管理. 1> 创建单例 其中的dispatch_once 的作用就是执行且在整个程序的声明周期中,仅执行一次某一个bloc ...
- Java虚拟机--垃圾收集
Java虚拟机 1. JVM运行时数据区域 参考书籍:<深入理解Java虚拟机:JVM高级特性与最佳实践,第二版> 资料参考:http://blog.csdn.net/nms312/art ...
- 【JAVASCRIPT】ECMAScrip (转)
部分ECMAScript术语 ECMAScript Sun(现在的Oracle)公司持有着"Java"和"JavaScript"的商标.这就让微软不得不把自己的 ...
- ASP.NET前台table通过Ajax获取绑定后台查询的json数据
上一篇<ASP.NET前台html页面AJAX提交数据后台ashx页面接收数据>写了前台提交数据后台保存到数据库,数据处理以后用户肯定要查询.接下来就写一个前台table通过ajax J ...
- Intger To Roman
这题意思是将一个输入的整型阿拉伯数字转化为罗马数字. 思路是将1-10对应的罗马数字放在字符串数组里,然后发现数据变化规律即可,eg:389 = 300 + 89 +9 分别对应的罗马数字. publ ...
- java中创建多线程两种方式以及实现接口的优点
多线程创建方式有两种 创建线程的第一种方式.继承Thread类 1.继承Thread类 2.重写Thread类中的run方法--目的将自定义代码存储在run方法.让线程执行3.调用线程的start() ...
- 看完给跪了:技术大牛总结的Github与华为软件开发云完整对比
华为软件开发云配置管理 服务和Github是国内外比较有代表性的代码托管平台,它们以git作为版本管理工具,使项目中身处各地的人员可以协同工作,主要操作涉及仓库.分支.提交.pull request等 ...
- swift UITextField光标聚焦以及光标颜色修改
光标聚焦闪烁: nick_textField.becomeFirstResponder() 光标颜色修改 nick_textField.tintColor = UIColor.red 备份:http: ...
- maven系列小技巧之Top3 MVQ(most valuable question)
首先声明,文章系个人原创 ,欢迎转载,转载请注明出处. 对于maven,有大神曾说过:如果你爱他,就请让他用Maven,因为那里是天堂,如果你恨他,就请让他用Maven,因为那里是地狱.尤其是mave ...