我爱网络流之最大流Dinic
直接上大佬博客:
模板步骤:
第一步,先bfs把图划分成分成分层图网络
第二步,dfs多次找增广路
当前弧优化:即每一次dfs增广时不从第一条边开始,而是用一个数组cur记录点u之前循环到了哪一条边,以此来加速
裸的最大流,直接按题意建图跑就行
#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 ;
}
小桥流水人家
也是个裸的最大流,不过得看得出来,就把每周每天视为节点,然后弄个汇点跟源点,跑一遍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
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的更多相关文章
- 网络流之最大流Dinic算法模版
/* 网络流之最大流Dinic算法模版 */ #include <cstring> #include <cstdio> #include <queue> using ...
- 网络流之最大流Dinic --- poj 1459
题目链接 Description A power network consists of nodes (power stations, consumers and dispatchers) conne ...
- 网络流(最大流-Dinic算法)
摘自https://www.cnblogs.com/SYCstudio/p/7260613.html 网络流定义 在图论中,网络流(Network flow)是指在一个每条边都有容量(Capacity ...
- [Poj2112][USACO2003 US OPEN] Optimal Milking [网络流,最大流][Dinic+当前弧优化]
题意:有K个挤奶机编号1~K,有C只奶牛编号(K+1)~(C+K),每个挤奶机之多能挤M头牛,现在让奶牛走到挤奶机处,求奶牛所走的最长的一条边至少是多少. 题解:从起点向挤奶机连边,容量为M,从挤奶机 ...
- 学习笔记 --- 最大流Dinic算法
为与机房各位神犇同步,学习下网络流,百度一下发现竟然那么多做法,最后在两种算法中抉择,分别是Dinic和ISAP算法,问过 CA爷后得知其实效率上无异,所以决定跟随Charge的步伐学习Dinic,所 ...
- 【Luogu2711】小行星(网络流,最大流)
[Luogu2711]小行星(网络流,最大流) 题面 题目描述 星云中有n颗行星,每颗行星的位置是(x,y,z).每次可以消除一个面(即x,y或z坐标相等)的行星,但是由于时间有限,求消除这些行星的最 ...
- 网络流(四)dinic算法
传送门: 网络流(一)基础知识篇 网络流(二)最大流的增广路算法 网络流(三)最大流最小割定理 网络流(四)dinic算法 网络流(五)有上下限的最大流 网络流(六)最小费用最大流问题 转自:http ...
- HDU 3416 Marriage Match IV (最短路径,网络流,最大流)
HDU 3416 Marriage Match IV (最短路径,网络流,最大流) Description Do not sincere non-interference. Like that sho ...
- HDU 3605 Escape (网络流,最大流,位运算压缩)
HDU 3605 Escape (网络流,最大流,位运算压缩) Description 2012 If this is the end of the world how to do? I do not ...
随机推荐
- Thinking In Java 4th Chap2 一切都是对象
对基本数据类型的初始化有二: 1.String s="asdf"; 2.String s=new String("asdf"); 可能的存储区域: 寄存器(不可 ...
- k8s-搭建 EFK 日志系统
搭建 EFK 日志系统 大家介绍了 Kubernetes 集群中的几种日志收集方案,Kubernetes 中比较流行的日志收集解决方案是 Elasticsearch.Fluentd 和 Kibana( ...
- bzoj 2734 集合悬殊 (状压dp)
大意: 给定$n$, 求集合{1,2,...n}的子集数, 满足若$x$在子集内, 则$2x,3x$不在子集内. 记$f(x)$为$x$除去所有因子2,3后的数, 那么对于所有$f$值相同的数可以划分 ...
- zookeeper客户端KeeperErrorCode = ConnectionLoss异常问题排查历险记
经过线报,说前方应用有异常,导致了可用性变差.咦!讨厌的异常,抛异常是程序猿最讨厌的事情之一. 经过收集异常信息如下 2019-06-24 10:57:41.806 ERROR [hades- ...
- C#签名验签帮助类
using System; using System.IO; using System.Text; using System.Collections.Generic; using System.Sec ...
- spring-boot-plus集成Shiro+JWT权限管理
SpringBoot+Shiro+JWT权限管理 Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理. 使用Shiro的易于理解的API,您可以 ...
- spring-cloud 学习三 服务提供者
基于spring-boot创建一个module提供服务 使用mysql数据库,dao使用mybatis,数据库连接池使用阿里的druid 添加maven依赖 <parent> <gr ...
- python+django学习二
所有模型类型的准备和迁移 在setting.py中添加:AUTH_USER_MODEL = 'users.UserProfile' 继承用户模板 确保子项目的url现在都是空的, 在pycharm的f ...
- Python中,标识符用法
Python中,标识符 在Python中,所有标识符都可以包括英文.数字和下划线(),但不能包括数字.python中的标识符区分大小写.这是知识的背景.但通常,Python成为以下划线开头的标识符的习 ...
- Vue项目中使用AES加密
1.在vue中安装crypto-js 备注:千万不要安装错了,中间是 ‘-’连接,不是‘.’ 2.在项目的工具文件夹中新建 encryption.js,用于定义加密和解密的方法,方便调用 ...