嘿嘿嘿,时隔不久又见到了DInic,再次回顾一下吧

 不过这次我倒是不想深究,而是想多做一些题,因为这几次比赛下来,算法不是重点,重点是题目如何转化,算法如何应用,这也是比赛为什么让你带着板子的原因吧,所以算法基本思想掌握了就好,不要去背,一看就能想通就行

Dinic算法通过bfs优先的分层处理,加以当前弧的优化,使得dfs寻找 最大流的更多,不像ff算法dfs效率低下,通过分层使得dfs明确了寻找方向,当前弧的优化,使得dfs寻边效率大大提高

Code

一些基本操作

#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
#define inf (1 << 28)
using namespace std;
typedef long long ll;
const int maxn = 220;
const int maxm = 4e4 + 4e2;
int n,m;
struct node{
int pre;
int to,cost;
}e[maxm];
int id[maxn],cnt;
//层数
int flor[maxn]; int cur[maxn];//DFS的优化遍历::当前弧优化 void add(int from,int to,int cost)
{
e[cnt].to = to;
e[cnt].cost = cost;
e[cnt].pre = id[from];
id[from] = cnt++;
swap(from,to);
e[cnt].to = to;
e[cnt].cost = 0;
e[cnt].pre = id[from];
id[from] = cnt++;
}

bfs分层处理

其实明白了思路,这个很简单就能写出来

int bfs(int s,int t)
{
memset(flor,0,sizeof(flor));
queue < int > q;
while(q.size())q.pop();
flor[s] = 1;
q.push(s); while(q.size())
{
int now = q.front();
q.pop();
for(int i = id[now];~i;i=e[i].pre)
{
int to = e[i].to;
int cost = e[i].cost;
if(flor[to] == 0 && cost > 0)
{
flor[to] = flor[now] + 1;
q.push(to);
if(to == t)return 1;
}
}
}
return 0;
}

dfs当前弧度的优化

dfs比较难懂,为什么要懂ff就是因为一切的算法都是以简单算法为基础的优化过来的

value:是s - s’的最大流(起始点为s)

ret:s' - t的残流(起始点为s’)

一层一层的递归,value - ret就是最大流了,具体还是理解代码展现出的思想

记得我第一次看的时候,dinic真的好绝望...看了n多篇博客,最后也没有

int dfs(int s,int t,int value)
{
//ret表示目前流到s的最大流量,用来计算回溯的时候是否还有可行流
int ret = value;
if(s == t || value == 0)return value; int a; for(int &i = cur[s];~i;i = e[i].pre)
{
int to = e[i].to;
int cost = e[i].cost;
if(flor[to] == flor[s] + 1 && (a = dfs(to,t,min(ret,cost))))
{
e[i].cost -= a;
e[i^1].cost += a;
ret -= a;
if(ret == 0)break;
}
}
//s点后面没有可行的流了,flor[s] = 0就表示废掉了这个点
if(ret == value) flor[s] = 0;
return value - ret;
}

DInic算法就是基于bfs来dfs的

int dinic(int s,int t)
{
ll ret = 0;
while(bfs(s,t))
{
memcpy(cur,id,sizeof(id));
ret += dfs(s,t,inf);
}
return ret;
}

其他的就简单啦

void init()
{
memset(id,-1,sizeof(id));
cnt = 0;
}
int main()
{
while(~scanf("%d%d",&m,&n))
{
init();
int a,b,x;
for(int i = 1;i <= m;++i)
{
scanf("%d%d%d",&a,&b,&x);
add(a,b,x);
}
ll ret = dinic(1,n);
printf("%lld\n",ret);
}
return 0;
}

最大流Dinic算法的更多相关文章

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

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

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

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

  3. Power Network(网络流最大流 & dinic算法 + 优化)

    Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 24019   Accepted: 12540 D ...

  4. 最大流——Dinic算法

    前面花了很长时间弄明白了压入-重标记的各种方法,结果号称是O(V3)的算法测demo的时候居然TLE了一个点,看了题解发现所有人都是用Dinic算法写的,但它的复杂度O(V2E)明显高于前者,具体是怎 ...

  5. 求最大流dinic算法模板

    //最短增广路,Dinic算法 struct Edge { int from,to,cap,flow; };//弧度 void AddEdge(int from,int to,int cap) //增 ...

  6. POJ 3469.Dual Core CPU 最大流dinic算法模板

    Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 24830   Accepted: 10756 ...

  7. hdu-3572 Task Schedule---最大流判断满流+dinic算法

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3572 题目大意: 给N个任务,M台机器.每个任务有最早才能开始做的时间S,deadline E,和持 ...

  8. P3376 【模板】网络最大流dinic算法

    P3376 [模板]网络最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点 ...

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

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

随机推荐

  1. 探索未知种族之osg类生物---呼吸分解之advance

    回顾 我们用了两节的内容才堪堪讲解完ViewerBase::frame()函数中调用的realize()---Viewer:: realize()函数.我们简单的总结就是Viewer:: realiz ...

  2. JavaScript中对数据库表中某一个字段进行赋值

    场景如下,通过下拉列表选择一个选项(如“启用”和“不启用”),启用用0表示,不启用用1表示. enableFlag是表中一个字段,我猜date:后面就是对该字段的赋值.

  3. BZOJ1899或洛谷2577 [ZJOI2005]午餐

    BZOJ原题链接 洛谷原题链接 解决这题得先想到一个贪心:吃饭慢的先排队. 并不会证明(感觉显然 设\(f[i][j][k]\)表示已经排好了前\(i\)人,第一个队伍需要花费的打饭时间为\(j\), ...

  4. JDK 之资源文件管理

    JDK 之资源文件管理 JDK 规范目录(https://www.cnblogs.com/binarylei/p/10200503.html) 一.文件资源 user.home 用户目录,如 Linu ...

  5. zookeeper相关

    1.zookeeper应用:集群节点间的数据同步(资源管理),分布式锁(主要是利用客户端在一个会话中在zookeeper中创建一个znode节点,然后再去执行自己的业务代码,比如去更新数据库,其他客户 ...

  6. python上下文管理协议

    所谓上下文管理协议,就是咱们打开文件时常用的一种方法:with __enter__(self):当with开始运行的时候触发此方法的运行 __exit__(self, exc_type, exc_va ...

  7. inet_pton和inet_ntop inet_ntoa

    Linux下地址转换函数 inet_pton ==> Ox inet_ntop ==> xxx.xxx.xxx #include <sys/types.h> #include ...

  8. Android音频系统之AudioFlinger(三)

    http://blog.csdn.net/xuesen_lin/article/details/8805091 1.1.1 PlaybackThread的循环主体 当一个PlaybackThread进 ...

  9. DOM-查找和修改

    1. 查找: 按HTML查找: 问题: 每次只能按一个条件查找,如果查找条件复杂,则步骤很繁琐 解决: 选择器: 按选择器查找: 2个API 1. 只查找一个元素: var elem=parent.q ...

  10. 再读c++primer plus 004

    第九章  内存模型和名称空间 1.如果文件名包含在尖括号中,则c++编译器将在存储标准头文件的主机系统的文件系统中查找,但如果文件名包含在双引号中,则编译器将首先查找当前的工作目录或源代码目录(或其他 ...