我学会了正确的dinic
时间:2019-06-11
本文章向大家介绍我学会了正确的dinic,主要包括我学会了正确的dinic使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
以前写Isap的时候,总是被卡,然后学了一发Isap的当前弧优化,好像可以水过很多题
但是一直没明白为啥Isap会走一个环???
然后写dinic了,听说不容易被卡(来自去年九省联考的指导)
然而……我写了一遍上下界最小流,T了。。
后来发现我还是不懂为啥要当前弧,因为不会有环
于是去询问群友……
说是会重复访问流满的边
那么为了防止这一点,记录一个边表的指针,流到了立马返回流量,这样流第二次过来的时候,就会从最近的一条没流满的边开始流了
然后扔个板子。。
感觉自己水平不行。。。
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define ba 47
//#define ivorysi
#define MAXN 50010
#define MAXM 200005
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 +c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
struct node {
int to,next,cap;
}E[MAXM * 2];
int N,M,S,T,s,t;
int head[MAXN],last[MAXN],sumE = 1,deg[MAXN],Sflow,low[MAXM],cur[MAXN];
int dis[MAXN];
void add(int u,int v,int c) {
E[++sumE].to = v;
E[sumE].next = head[u];
E[sumE].cap = c;
head[u] = sumE;
}
void addtwo(int u,int v,int c) {
add(u,v,c);add(v,u,0);
}
queue<int> Q;
bool BFS() {
memset(dis,0,sizeof(dis));
while(!Q.empty()) Q.pop();
Q.push(S);dis[S] = 1;
while(!Q.empty()) {
int u = Q.front();Q.pop();
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(E[i].cap > 0) {
if(!dis[v]) {
dis[v] = dis[u] + 1;
if(v == T) return true;
Q.push(v);
}
}
}
}
return dis[T] != 0;
}
int dfs(int u,int aug) {
if(u == T) return aug;
for(int &i = cur[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(E[i].cap > 0) {
if(dis[v] == dis[u] + 1) {
int t = dfs(v,min(E[i].cap,aug));
if(t) {
E[i].cap -= t;
E[i ^ 1].cap += t;
return t;
}
}
}
}
return 0;
}
int Dinic() {
int res = 0;
while(BFS()) {
memcpy(cur,head,sizeof(head));
while(int d = dfs(S,1e9)) {
res += d;
}
}
return res;
}
void Solve() {
read(N);read(M);read(s);read(t);
S = N + 1;T = S + 1;
int a,b,u,l;
for(int i = 1 ; i <= M ; ++i) {
read(a);read(b);read(l);read(u);
addtwo(a,b,u - l);
low[i] = l;
deg[a] -= l;
deg[b] += l;
}
for(int i = 1 ; i <= N ; ++i) {
if(deg[i] > 0) {addtwo(S,i,deg[i]);Sflow += deg[i];}
else addtwo(i,T,-deg[i]);
}
Sflow -= Dinic();
addtwo(t,s,1e9);
Sflow -= Dinic();
if(Sflow != 0) puts("please go home to sleep");
else {out(E[sumE].cap);enter;}
}
int main(){
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
原文地址:https://www.cnblogs.com/ivorysi/p/11003262.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Tensorflow tensor 数学运算和逻辑运算方式
- Tensorflow全局设置可见GPU编号操作
- YII框架http缓存操作示例
- 基于tf.shape(tensor)和tensor.shape()的区别说明
- PHP检查URL包含特定字符串实例方法
- Python使用xlrd实现读取合并单元格
- python模块如何查看
- YII框架页面缓存操作示例
- PHP chunk_split()函数讲解
- Python3爬虫中Ajax的用法
- stripos函数知识点实例分享
- PHP实现字符串大小写转函数的功能实例
- 在django中实现choices字段获取对应字段值
- python语言中有算法吗
- jQuery ajax+PHP实现的级联下拉列表框功能示例