前言

摆王兴致冲冲地跑到我们机房来对我说跟你讲一个黑科技。。。

Dinic的神奇优化

Dinic优化

我们发现如果Dinic不建反向边会跑的飞起(当然Wa是必然的)
所以考虑在加反向边的基础上优化.

首先我们记录网络中最大的一个流量,设它为Min,然后:

  1. 把所有小于Min的边都加入网络中
  2. 最大流+=Dinic()
  3. Min /= 2
  4. 到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跑得快的更多相关文章

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

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

  2. [无效]网络流之Dinic算法

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

  3. 网络流系列算法总结(bzoj 3438 1061)

    网络流嘛,怎么看都是一堆逗逼题嘛,反正遇到还是都做不起嘛.... 网络流的模板非常简单,难点都在于建图,网络流的建图解决问题范围之广,下至A+B Problem,上至单纯形,线性规划.所以如果对于网络 ...

  4. 「CODVES 1922 」骑士共存问题(二分图的最大独立集|网络流)&dinic

    首先是题目链接  http://codevs.cn/problem/1922/ 结果发现题目没图(心情复杂 然后去网上扒了一张图 大概就是这样了. 如果把每个点和它可以攻击的点连一条边,那问题就变成了 ...

  5. 网络流 KM dinic

    study from: https://blog.csdn.net/A_Comme_Amour/article/details/79356220 1. Edmonds-Karp 无优化 最坏时间复杂度 ...

  6. 初涉网络流[EK&dinic]

    主要还是板子 Edmonds-Karp 从S开始bfs,直到找到一条到达T的路径后将该路径增广,并重复这一过程. 在处理过程中,为了应对“找到的一条路径把其他路径堵塞”的情况,采用了建反向弧的方式来实 ...

  7. 网络流之Dinic算法

    初学网络流.存一下Dinic板子. 复杂度O(n^2*m) UVA - 1515 Pool construction 把每个草地与 S 相连,花费为dig,每个洞与 T 相连,花费为 然后对于每个两个 ...

  8. 网络流 之 dinic 算法

    网络流指的是:网络流(network-flows)是一种类比水流的解决问题方法.(类似于水管群,有一个源点(水无限多),和一个汇点,最大流就代表这个点水管群(边集)每秒最大能送道汇点的水量) 这个怎么 ...

  9. 初探网络流:dinic/EK算法学习笔记

    前记 这些是初一暑假的事: "都快初二了,连网络流都不会,你好菜啊!!!" from 某机房大佬 to 蒟蒻我. flag:--NOIP后要学网络流 咕咕咕------------ ...

随机推荐

  1. DB2 OLAP函数的使用

    说起 DB2 在线分析处理,可以用很好很强大来形容.这项功能特别适用于各种统计查询,这些查询用通常的SQL很难实现,或者根本就无发实现.首先,我们从一个简单的例子开始,来一步一步揭开它神秘的面纱,请看 ...

  2. HXY玩卡片(水题测试2017082401&洛谷2192)

    题目链接:HXY玩卡片 很水, 简单讲一下思路. 如果没有0,直接无解,因为不可能是10的倍数. 是9的倍数,则各个数位上的数字和为9的倍数,所以5的数量一定是9的倍数,所以只要尽可能多输出9的倍数个 ...

  3. Java第3章笔记

    if基本语法: if(条件){// 表达式   // 代码块   } eg:    int a = 10;    if(a > 1){  System.out.println("内容& ...

  4. Codeforces 1107 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意简述:问你能不能把一个数字串切成若干块,使得切出来的kkk个数k≤2k\le2k≤2满足a1<a2<...&l ...

  5. 2018.12.30 bzoj3027: [Ceoi2004]Sweet(生成函数+搜索)

    传送门 生成函数好题. 题意简述:给出n个盒子,第iii个盒子里有mim_imi​颗相同的糖(但不同盒子中的糖不相同),问有多少种选法可以从各盒子中选出数量在[a,b][a,b][a,b]之间的糖果. ...

  6. 使用Ant发布web应用到tomcat

    使用Ant发布web应用到tomcat 来自:http://blog.csdn.net/hbcui1984/article/details/1954537 今天在公司用ant写了个部署web应用的脚本 ...

  7. poj-2406(字符串hash)

    题目链接:传送门 思路:字符串hash,终止条件竟然判断错了,真是太大意了. #include<iostream> #include<cstdio> #include<c ...

  8. (线段树 区间运算求点)Flowers -- hdu -- 4325

    http://acm.hdu.edu.cn/showproblem.php?pid=4325 Flowers Time Limit: 4000/2000 MS (Java/Others)    Mem ...

  9. A Magic Lamp -- hdu -- 3183

    http://acm.hdu.edu.cn/showproblem.php?pid=3183 A Magic Lamp Time Limit: 2000/1000 MS (Java/Others)   ...

  10. 2017-2018-1 201552326《信息安全技术》实验二——Windows口令破解

    2017-2018-1 201552326<信息安全技术>实验二--Windows口令破解 姓名:刘美岑 学号:20155326 班级:1553班 日期:10.24 一.实验环境 操作系统 ...