不一样的网络流系列——Dinic跑得快
前言
摆王兴致冲冲地跑到我们机房来对我说跟你讲一个黑科技。。。
Dinic的神奇优化
Dinic优化
我们发现如果Dinic不建反向边会跑的飞起(当然Wa是必然的)
所以考虑在加反向边的基础上优化.
首先我们记录网络中最大的一个流量,设它为Min,然后:
- 把所有小于Min的边都加入网络中
- 最大流+=Dinic()
- Min /= 2
- 到1
然后在Dinic时不走反向边(但是值要改变),最后在可以走反向边的情况下再来一次
注意bfs的一些操作,如果不当会溢出...
代码实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
#define int ll
inline int gi()
{
int f=1,sum=0;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
const int N=500010,M=2000010,Inf=1e10+10;
int n,m,s,t,ans,dep[N],cur[N];
struct node
{
int u,v,c;
}E[M];
vector<int>front[N];
vector<node>e;
void Add(int u,int v,int c)
{
e.push_back((node){u,v,c});
e.push_back((node){v,u,0});
front[u].push_back(e.size()-2);
}
bool cmp(node a,node b)
{
return a.c>b.c;
}
queue<int>Q;
bool bfs()
{
memset(dep,127,sizeof(dep));
Q.push(s);dep[s]=0;
while(!Q.empty())
{
int u=Q.front();Q.pop();
for(int i=0;i<front[u].size();i++)
{
int id=front[u][i];
int v=e[id].v;
if(dep[v]>1e9 && e[id].c)
{
dep[v]=dep[u]+1;
Q.push(v);
}
}
}
return dep[t]<1e9;
}
int dfs(int u,int flow)
{
// printf("%lld %lld\n",u,flow);
if(!flow || u==t)return flow;
int F=0;
for(int &i=cur[u];i<front[u].size();i++)
{
int id=front[u][i];
if(dep[e[id].v]==dep[u]+1 && e[id].c)
{
int di=dfs(e[id].v,min(flow,e[id].c));
if(di)
{
e[id].c-=di;e[id^1].c+=di;
flow-=di;F+=di;
if(!flow)break;
}
else dep[e[id].v]=0;
}
}
return F;
}
int Dinic()
{
int flow=0;
while(bfs())
{
for(int i=1;i<=n;i++)cur[i]=0;
while(int d=dfs(s,Inf))flow+=d;
}
return flow;
}
signed main()
{
n=gi();m=gi();s=gi();t=gi();
for(int i=0;i<m;i++)
{
int u=gi(),v=gi(),c=gi();
E[i]=(node){u,v,c};
}
sort(E,E+m,cmp);
for(int type=0;type<2;type++){
for(int p=1<<30,now=0;p;p>>=1)
{
while(now<m && E[now].c>=p)
{
if(!type)Add(E[now].u,E[now].v,E[now].c);
else front[E[now].v].push_back(now*2+1);
now++;
}
ans+=Dinic();
}
}
printf("%lld\n",ans);
return 0;
}
不一样的网络流系列——Dinic跑得快的更多相关文章
- [知识点]网络流之Dinic算法
// 此博文为迁移而来,写于2015年2月6日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vrg4.html ...
- [无效]网络流之Dinic算法
// 此博文为迁移而来,写于2015年2月6日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vrg4.html UPDA ...
- 网络流系列算法总结(bzoj 3438 1061)
网络流嘛,怎么看都是一堆逗逼题嘛,反正遇到还是都做不起嘛.... 网络流的模板非常简单,难点都在于建图,网络流的建图解决问题范围之广,下至A+B Problem,上至单纯形,线性规划.所以如果对于网络 ...
- 「CODVES 1922 」骑士共存问题(二分图的最大独立集|网络流)&dinic
首先是题目链接 http://codevs.cn/problem/1922/ 结果发现题目没图(心情复杂 然后去网上扒了一张图 大概就是这样了. 如果把每个点和它可以攻击的点连一条边,那问题就变成了 ...
- 网络流 KM dinic
study from: https://blog.csdn.net/A_Comme_Amour/article/details/79356220 1. Edmonds-Karp 无优化 最坏时间复杂度 ...
- 初涉网络流[EK&dinic]
主要还是板子 Edmonds-Karp 从S开始bfs,直到找到一条到达T的路径后将该路径增广,并重复这一过程. 在处理过程中,为了应对“找到的一条路径把其他路径堵塞”的情况,采用了建反向弧的方式来实 ...
- 网络流之Dinic算法
初学网络流.存一下Dinic板子. 复杂度O(n^2*m) UVA - 1515 Pool construction 把每个草地与 S 相连,花费为dig,每个洞与 T 相连,花费为 然后对于每个两个 ...
- 网络流 之 dinic 算法
网络流指的是:网络流(network-flows)是一种类比水流的解决问题方法.(类似于水管群,有一个源点(水无限多),和一个汇点,最大流就代表这个点水管群(边集)每秒最大能送道汇点的水量) 这个怎么 ...
- 初探网络流:dinic/EK算法学习笔记
前记 这些是初一暑假的事: "都快初二了,连网络流都不会,你好菜啊!!!" from 某机房大佬 to 蒟蒻我. flag:--NOIP后要学网络流 咕咕咕------------ ...
随机推荐
- 通过SD卡来安装Linux系统
一.制作SD启动卡(安装Linux)步骤: 烧写原理:superboot-6410.bin(bootloader)+内核镜像文件+根文件系统 1.将SD卡插入USB接口的读卡器,并插在PC的USB口 ...
- linux代码笔记
sudo passwd root更新root密码 软件包管理及shell命令_deb软件包管理一_笔记:dpkj -i 安装dpkj -r 移除dpkj -P 全部移除dpkj -L 列出安装清单dj ...
- 前端之css操作2
一 伪类选择器 伪类选择器就是在查找的后面加上冒号和状态 hover:悬浮到上面就会变化一种状态 link:没有接触的状态 active:点击是触发的状态 visited:点击后的状态 <!DO ...
- Python10/22--面向对象编程/类与对象/init函数
类: 语法: class关键字 类名# 类名规范 大写开头 驼峰命名法class SHOldboyStudent: # 描述该类对象的特征 school = "上海Oldboy" ...
- IDEA将项目导出war包方法(详细)
右上角点击进入配置页面(如图)选择Artifcts 点击绿色的那个+号,选择Web Application:Archive; 设置名称,选择输出路径 下面开始打war包在Build下面选择Build ...
- SVN安装配置与使用
http://www.cnblogs.com/skyway/archive/2011/08/10/2133399.html http://www.cnblogs.com/lidabo/archive/ ...
- VMware 14 tools位置;
安装后默认位置: CD读入 然后,启动虚拟机. 1.创建挂载点 mkdir /mnt/cdrom 2.挂在光驱 mount /dev/cdrom /mnt/cdrom(我的这句无效) 3.查看 cd ...
- win8快捷键大全分享,非常全
Windows 8全新的Metro操作体验,对于没有平板只能用快捷键来提高效率了.全面的Windows 8快捷键,请下载微软官方的Windows 8快捷键表格,快捷键全记完整个人都斯巴达了..其实常用 ...
- Kotlin入门
转载自:https://www.cnblogs.com/jaymo/articles/6924144.html 创建类的实例 要创建一个类的实例,我们就像普通函数一样调用构造函数: 1 2 3 val ...
- 解决编译错误:cc: Internal error: Killed (program cc1)
错误现象: cc: Internal error: Killed (program cc1) ... 大体上是因为内存不足,临时使用交换分区来解决吧 sudo mkswap /swapfile sud ...