赛前赛后算是第三次接触Dinic算法了,每一次接触都能有种很好的感觉,直男的我没法描述~~

已经比较懂得DInic的基本算法思想了

首先是bfs进行进行分层处理,然后dfs寻找分层后的最大流,在这其中做好正向边流量和反向边流量的优化处理

bfs依旧是比较的简单,维护flor的数组

dfs依旧是Dinic的精华

int dfs(int s,int t,int value)
{
int ret = value;
if(s == t || value == )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] + && (a = dfs(to,t,min(ret,e[i].cost))))
{
e[i].cost -= a;
e[i ^ ].cost += a;
ret -= a;
if(ret == )break;
}
} if(ret == value)flor[s] = ;
return value - ret;
}
从s到t,value为其路径上的最大流量值
然后访问分层后的边(仅仅访问一次)往下继续留,递归回来的时候进行正向边和反向边的流量优化
最最后面删点,删去此次分层后被截流的点 然后根据优化后的网络流继续分层,直到分层结束。、、

/*
Dinic算法求取最小费用最大流问题
必要的概念:
前向弧:方向与链正方向一致的弧——p+
后向弧:方向与链反方向一致的弧——p-
增广路:也称为可改进路径,对于一条可行流,存在p
满足p的所有前向弧都是非饱和的,
p的所有后向弧都是非零流弧

割:去除摸一个点后使基图不在连通,
也就是将原来的两个点集划分为两个子集S和T

s-t割:分割后的两个子集,远点s属于S,汇点t属于T
s-t割后的弧u-v,u属于sv属于t的为前向弧,反之为后向弧

割的容量:前向弧的容量和
最小割:使容量最小的割

*/
/*
最大流
也就是寻找增广路
1.现在是零流
2.(当前情况下)寻找一条路,从s到t,并且每一段的流量都小于容量(并不是小于等于!!流量代表的是当前的流量,如果想等就不再可行)
3.那么找到这条路上的min(容量 - 流量),然后每一段的流量都加上delta(这就叫增广路)
4.重复步骤二,知道找不到增广路
以上为基础算法思想
*/
/*
逐步的优化
反向边:为了求出最大流
反向边的出现给了流浪一个反向的几回,虽然有重复的部分但是能确保反向增广后,可以得到两条独一无二的链!
在说的明白一点反向的可行性是建立在可以退流的基础上,像二分图匹配似的
*/
/*
Dinic算法
1》初始化容量网络和网络流
2》构造残留网络和层次网络,若汇点不在层次网络之中结束
3》对层次网络进行DFS,进行增广
4》重复步骤二
*/
#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
#define inf 0xffffff

using namespace std;
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];

void init()
{
    memset(id,-1,sizeof(id));
    cnt = 0;
}

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++;
    //可以用异或去取他的反向边
    //偶数为正向,奇数为反向
}
int bfs(int s,int t)
{
    memset(flor,0,sizeof(flor));
    queue<int>q;
    while(q.size())q.pop();

flor[s] = 1;//flor还充当vis数组,所以从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;

}
int dfs(int s,int t,int value)
{
    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,e[i].cost))))
        {
            e[i].cost -= a;
            e[i ^ 1].cost += a;
            ret -= a;
            if(ret == 0)break;
        }
    }

if(ret == value)flor[s] = 0;
    return value - ret;
}
int Dinic(int s,int t)
{
    int ret = 0;
    while(bfs(s,t))
    {
        memcpy(cur,id,sizeof(id));
//        for(int i = 0;i < n;i++)
//        {
//            cur[i] = id[i];
//        }
        ret += dfs(s,t,inf);
        //cout<<"cs"<<endl;
    }
    return ret;
}
int main()
{
/*
5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
*/
    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);
        }
        int ret = Dinic(1,n);
        printf("%d\n",ret);
    }
    return 0;
}

/*不知道什么时候的事了,博客园的代码插入位置咋不能在光标之后了,一开始就是因为CSDN的不好编辑才用的博客园哎~~*/

Dinic算法——重述的更多相关文章

  1. ACM/ICPC 之 Dinic算法(POJ2112)

    Optimal Milking //二分枚举最大距离的最小值+Floyd找到最短路+Dinic算法 //参考图论算法书,并对BFS构建层次网络算法进行改进 //Time:157Ms Memory:65 ...

  2. ISAP算法对 Dinic算法的改进

    ISAP算法对 Dinic算法的改进: 在刘汝佳图论的开头引言里面,就指出了,算法的本身细节优化,是比较复杂的,这些高质量的图论算法是无数优秀算法设计师的智慧结晶. 如果一时半会理解不清楚,也是正常的 ...

  3. [知识点]网络流之Dinic算法

    // 此博文为迁移而来,写于2015年2月6日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vrg4.html      ...

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

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

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

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

  6. HDU 1532 (Dinic算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1532 题目大意: 就是由于下大雨的时候约翰的农场就会被雨水给淹没,无奈下约翰不得不修建水沟,而且是网络 ...

  7. poj 1459 Power Network : 最大网络流 dinic算法实现

    点击打开链接 Power Network Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 20903   Accepted:  ...

  8. POJ 1273 Drainage Ditches(网络流dinic算法模板)

    POJ 1273给出M条边,N个点,求源点1到汇点N的最大流量. 本文主要就是附上dinic的模板,供以后参考. #include <iostream> #include <stdi ...

  9. 【BZOJ】1001: [BeiJing2006]狼抓兔子 Dinic算法求解平面图对偶图-最小割

    1001: [BeiJing2006]狼抓兔子 Description 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下 三种类型的道路 1:(x,y)<==>( ...

随机推荐

  1. 转 java反射详解

    本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象 ...

  2. PAT 1017 A除以B(20)(代码)

    1017 A除以B(20 分) 本题要求计算 A/B,其中 A 是不超过 1000 位的正整数,B 是 1 位正整数.你需要输出商数 Q 和余数 R,使得 A=B×Q+R 成立. 输入格式: 输入在一 ...

  3. PHP swoole process的使用

    引入背景:假如我们每天有10000个订单生成,需要同步到仓储系统中去,以前做法是开启一个crontab去跑这些任务,但是发现总有感觉同步效率低,间隔时间都是分钟级别的. 解决方案测试:我们将同步订单的 ...

  4. vue 中使用keepAlive状态保持

      keepAlive状态保持 1 主要实现原理,状态保持的路由不会执行生命周期的钩子函数,只有第一次进入页面会执行钩子函数. 2 设置当前页面保持keepAlive 直接在路由meta中配置即可 m ...

  5. python爬虫 urllib库基本使用

    以下内容均为python3.6.*代码 学习爬虫,首先有学会使用urllib库,这个库可以方便的使我们解析网页的内容,本篇讲一下它的基本用法 解析网页 #导入urllib from urllib im ...

  6. csdn博客

    https://blog.csdn.net/lydstory123?t=1 以前还有几篇文章  忘记了

  7. java指针与引用(转载)

    大家都知道java和C#中没有指针这个概念.但是也导致了编程中常常忽略了对象与引用的区别,难道java真的没有指针吗?句柄是什么?变量地址在哪里?没有地址是不可能的,关键是java中如何避免了指针这个 ...

  8. swift 官方获取JSON 数据方法

    var url = NSURL(string: "http://www.weather.com.cn/data/sk/101120501.html") var data = NSD ...

  9. 软件测试基础Ⅲ(osi7层协议,测试模型,LoadRunner组件,软件质量模型)

    osi7层开放式系统互连网络模型 1.物理层:主要定义物理设备标准,如网线的接口类型.光纤的接口类型.各种传输介质的传输速率等.它的主要作用是传输比特流(就是由1.0转化为电流强弱来进行传输,到达目的 ...

  10. Vue 汇总

    1.右键菜单(防止默认行为) @contextmenu.native.prevent="rightClick()"