直接上大佬博客:

Dinic算法详解及实现来自小菲进修中

Dinic算法(研究总结,网络流)来自SYCstudio

  模板步骤:

  第一步,先bfs把图划分成分成分层图网络

  第二步,dfs多次找增广路

  当前弧优化:即每一次dfs增广时不从第一条边开始,而是用一个数组cur记录点u之前循环到了哪一条边,以此来加速

POJ - 1273Drainage Ditches

  裸的最大流,直接按题意建图跑就行

 #include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int N=,inf=;
struct Side{
int v,ne,w;
}S[N<<];
int n,sn,head[N],cur[N],dep[N];
void init()
{
sn=;
for(int i=;i<=n;i++)
head[i]=-;
}
void add(int u,int v,int w)
{
S[sn].v=v;
S[sn].w=w;
S[sn].ne=head[u];
head[u]=sn++;
}
void addE(int u,int v,int w)
{
add(u,v,w);
add(v,u,);
}
bool bfs()
{
queue<int> q;
for(int i=;i<=n;i++)
dep[i]=;
dep[]=;
q.push();
int x,y;
while(!q.empty())
{
x=q.front();
q.pop();
for(int i=head[x];~i;i=S[i].ne)
{
y=S[i].v;
if(S[i].w>&&!dep[y])
{
dep[y]=dep[x]+;
q.push(y);
}
}
}
return dep[n]!=;
}
int dfs(int u,int minf)
{
if(u==n||!minf)
return minf;
int v,flow;
for(int &i=cur[u];~i;i=S[i].ne)
{
v=S[i].v;
if(dep[v]==dep[u]+&&S[i].w>)
{
flow=dfs(v,min(minf,S[i].w));
if(flow)
{
S[i].w-=flow;
S[i^].w+=flow;
return flow;
}
}
}
return ;
}
int dinic()
{
int ans=,flow;
while(bfs())
{
for(int i=;i<=n;i++)
cur[i]=head[i];
while(flow=dfs(,inf))
ans+=flow;
}
return ans;
}
int main()
{
int m,u,v,w;
while(~scanf("%d%d",&m,&n))
{
init();
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
addE(u,v,w);
}
printf("%d\n",dinic());
}
return ;
}

小桥流水人家

POJ - 1698Alice's Chance

  也是个裸的最大流,不过得看得出来,就把每周每天视为节点,然后弄个汇点跟源点,跑一遍dinic看最大流是不是总要求的天数

 #include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int N=,inf=;
struct Side{
int v,ne,w;
}S[N<<];
struct Film{
int ok[],day,week;
}F[N];
int n,sn,sum,sb,se,head[N],cur[N],dep[N];
void init()
{
sn=,sum=;
sb=,se=n+;
for(int i=;i<=se;i++)
head[i]=-;
}
void add(int u,int v,int w)
{
S[sn].v=v;
S[sn].w=w;
S[sn].ne=head[u];
head[u]=sn++;
}
void addE(int u,int v,int w)
{
add(u,v,w);
add(v,u,);
}
bool bfs()
{
queue<int> q;
for(int i=;i<=se;i++)
dep[i]=;
dep[sb]=;
q.push(sb);
int u,v;
while(!q.empty())
{
u=q.front();
q.pop();
for(int i=head[u];~i;i=S[i].ne)
{
v=S[i].v;
if(S[i].w>&&!dep[v])
{
dep[v]=dep[u]+;
q.push(v);
}
}
}
return dep[se]!=;
}
int dfs(int u,int minf)
{
if(u==se||!minf)
return minf;
int v,flow;
for(int &i=cur[u];~i;i=S[i].ne)
{
v=S[i].v;
if(S[i].w>&&dep[v]==dep[u]+)
{
flow=dfs(v,min(minf,S[i].w));
if(flow>)
{
S[i].w-=flow;
S[i^].w+=flow;
return flow;
}
}
}
return ;
}
int dinic()
{
int ans=,flow;
while(bfs())
{
for(int i=;i<=se;i++)
cur[i]=head[i];
while(flow=dfs(sb,inf))
ans+=flow;
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
init();
for(int i=;i<=n;i++)
{
for(int j=;j<=;j++)
scanf("%d",&F[i].ok[j]);
scanf("%d%d",&F[i].day,&F[i].week);
sum+=F[i].day;
}
for(int i=;i<=n;i++)
addE(sb,i,F[i].day);
for(int i=;i<=n;i++)
{
for(int j=;j<F[i].week;j++)
for(int k=;k<=;k++)
if(F[i].ok[k])
addE(i,n+j*+k,);
}
for(int i=;i<;i++)
for(int j=;j<=;j++)
addE(n+i*+j,se,);
if(dinic()>=sum)
printf("Yes\n");
else
printf("No\n");
}
return ;
}

one day day

HDU 3605Escape

  100000个人,但才10个星球,在建图上,把可以去的星球状态相同的人视为一样的,这样最多就才1024个状态,然后跑一遍dinic,c++直接交,g++的话得用快读。

 #include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int N=<<,inf=;
struct Side{
int v,ne,w;
}S[N<<];
int sn,pb,pe,n,m,head[N],cur[N];
int cf2[]={},man[N],dep[N];
//int read()
//{
// int res = 0, flg = 1; char chr = getchar();
// while(chr < '0' || chr > '9') {if(chr == '-') res = -1; chr = getchar();}
// while(chr <= '9' && chr >= '0') {res = res * 10 + chr - '0'; chr = getchar();}
// return res * flg;
//}g++用快读
void init()
{
sn=;
pb=,pe=cf2[m]+m;
for(int i=;i<cf2[m];i++)
man[i]=;
for(int i=;i<=pe;i++)
head[i]=-;
}
void add(int u,int v,int w)
{
S[sn].w=w;
S[sn].v=v;
S[sn].ne=head[u];
head[u]=sn++;
}
void addE(int u,int v,int w)
{
add(u,v,w);
add(v,u,);
}
bool bfs()
{
for(int i=;i<=pe;i++)
dep[i]=;
dep[pb]=;
queue<int> q;
q.push(pb);
int u,v;
while(!q.empty())
{
u=q.front();
q.pop();
for(int i=head[u];~i;i=S[i].ne)
{
v=S[i].v;
if(S[i].w>&&!dep[v])
{
dep[v]=dep[u]+;
q.push(v);
}
}
}
return dep[pe]!=;
}
int dfs(int u,int minf)
{
if(u==pe||!minf)
return minf;
int v,flow;
for(int &i=cur[u];~i;i=S[i].ne)
{
v=S[i].v;
if(S[i].w>&&dep[v]==dep[u]+)
{
flow=dfs(v,min(minf,S[i].w));
if(flow)
{
S[i].w-=flow;
S[i^].w+=flow;
return flow;
}
}
}
return ;
}
int dinic()
{
int maxf=,flow;
while(bfs())
{
for(int i=;i<=pe;i++)
cur[i]=head[i];
while(flow=dfs(pb,inf))
maxf+=flow;
}
return maxf;
}
int main()
{
for(int i=;i<=;i++)
cf2[i]=cf2[i-]<<;
int num,x;
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=;i<=n;i++)
{
num=;
for(int j=;j<m;j++)
{
scanf("%d",&x);
if(x)
num|=cf2[j];
}
man[num]++;
}
for(int i=;i<cf2[m];i++)
if(man[i])
{
addE(pb,i,man[i]);
for(int j=;j<m;j++)
if(i&cf2[j])
addE(i,cf2[m]+j,man[i]);
}
for(int i=;i<m;i++)
{
scanf("%d",&x);
addE(cf2[m]+i,pe,x);
}
if(dinic()>=n)
printf("YES\n");
else
printf("NO\n");
}
return ;
}

流浪星球

  啊,网络流就在于建图。

我爱网络流之最大流Dinic的更多相关文章

  1. 网络流之最大流Dinic算法模版

    /* 网络流之最大流Dinic算法模版 */ #include <cstring> #include <cstdio> #include <queue> using ...

  2. 网络流之最大流Dinic --- poj 1459

    题目链接 Description A power network consists of nodes (power stations, consumers and dispatchers) conne ...

  3. 网络流(最大流-Dinic算法)

    摘自https://www.cnblogs.com/SYCstudio/p/7260613.html 网络流定义 在图论中,网络流(Network flow)是指在一个每条边都有容量(Capacity ...

  4. [Poj2112][USACO2003 US OPEN] Optimal Milking [网络流,最大流][Dinic+当前弧优化]

    题意:有K个挤奶机编号1~K,有C只奶牛编号(K+1)~(C+K),每个挤奶机之多能挤M头牛,现在让奶牛走到挤奶机处,求奶牛所走的最长的一条边至少是多少. 题解:从起点向挤奶机连边,容量为M,从挤奶机 ...

  5. 学习笔记 --- 最大流Dinic算法

    为与机房各位神犇同步,学习下网络流,百度一下发现竟然那么多做法,最后在两种算法中抉择,分别是Dinic和ISAP算法,问过 CA爷后得知其实效率上无异,所以决定跟随Charge的步伐学习Dinic,所 ...

  6. 【Luogu2711】小行星(网络流,最大流)

    [Luogu2711]小行星(网络流,最大流) 题面 题目描述 星云中有n颗行星,每颗行星的位置是(x,y,z).每次可以消除一个面(即x,y或z坐标相等)的行星,但是由于时间有限,求消除这些行星的最 ...

  7. 网络流(四)dinic算法

    传送门: 网络流(一)基础知识篇 网络流(二)最大流的增广路算法 网络流(三)最大流最小割定理 网络流(四)dinic算法 网络流(五)有上下限的最大流 网络流(六)最小费用最大流问题 转自:http ...

  8. HDU 3416 Marriage Match IV (最短路径,网络流,最大流)

    HDU 3416 Marriage Match IV (最短路径,网络流,最大流) Description Do not sincere non-interference. Like that sho ...

  9. HDU 3605 Escape (网络流,最大流,位运算压缩)

    HDU 3605 Escape (网络流,最大流,位运算压缩) Description 2012 If this is the end of the world how to do? I do not ...

随机推荐

  1. 标准库中最值得关注的两个 装饰器是 lru_cache 和全新的 singledispatch(Python 3.4 新增)

    clock 装饰器 def clock(func): @functools.wraps(func) def clocked(*args, **kwargs): t0 = time.perf_count ...

  2. linux 下使用opengl的glut库显示和旋转BMP图片

    效果图: 这里显示的图和原图有明显的色差,目前猜测是opengl渲染时的颜色表顺序跟BMP文件里的颜色表顺序相反导致. BMP里应该是BGRBGRBRG... ,而opengl渲染时应该是按照RGBR ...

  3. service程序改为windows窗体展示

    首先将exe程序文件进行快捷创建.然后就会生成一个 exe -shortCut 程序,然后进入属性中,并且进行修改引用路径,在路径xx.exe 后面加一个空格和/tt,保存,这样就可以正常运行了. 如 ...

  4. AOP底层实现原理,动态代理如何动态

    代理 指定另外一个主体代替原来的某个主体去执行某个事物 代理执行的人 需要代理的人 需要代理的事情是一定要做的 但是被代理的人没有时间或自己做的不专业 静态代理: 父母朋友帮忙物色找对象 代理人掌握需 ...

  5. 好好讲一讲,到底什么是Java高级架构师!

    一. 什么是架构师 曾经有这么个段子: 甲:我已经应聘到一家中型软件公司了,今天上班的时候,全公司的人都来欢迎我. 乙:羡慕ing,都什么人来了? 甲:CEO.COO.CTO.All of 程序员,还 ...

  6. 【Day3】1.正则表达式

    1.正则表达式 2.案例 关闭贪婪模式

  7. python基础:数据类型二

    一.元组类型 二.字典类型 三.集合 一.元组类型 # 什么是元组: 元组就是一个不可变的列表 # ======================================基本使用======== ...

  8. PAT Basic 1083 是否存在相等的差 (20 分)

    给定 N 张卡片,正面分别写上 1.2.…….N,然后全部翻面,洗牌,在背面分别写上 1.2.…….N.将每张牌的正反两面数字相减(大减小),得到 N 个非负差值,其中是否存在相等的差? 输入格式: ...

  9. 集合篇-----ArrayList与LinkedList之间的那些小事

    各自特性: ArrayList  : 是一由连续的内存块组成的数组,范围大小可变的,当不够时增加为原来1.5倍大小,数组. :调用trimToSize方法,使得存储区域的大小调整为当前元素数量所需要的 ...

  10. CP and Tucker Tensor Decomposition

    1.. 2..