Dinic算法最大流入门

例题传送门

Dinic算法是网络流最大流的优化算法之一,每一步对原图进行分层,然后用DFS求增广路。时间复杂度是O(n^2*m),Dinic算法最多被分为n个阶段,每个阶段包括建层次网络和寻找增广路两部分。

Dinic算法的思想是分阶段地在层次网络中增广。它与最短增广路算法不同之处是:最短增广路每个阶段执行完一次BFS增广后,要重新启动BFS从源点Vs开始寻找另一条增广路;而在Dinic算法中,只需一次BFS过程就可以实现多次增广。

简单来说,分为下面几步:

  1.在剩余网络中查找是否存在从S到T的路径,同时建分层图。

    分层图的层数其实就是S到i这个点需要几步。

  2.沿着分层图多路增广。

    增广时一定要满足dist[j]=dist[i]+1。

  3.直到没有S到T的路径是结束算法。

code:

#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;

char tc()
{
    static char fl[100000],*A=fl,*B=fl;
    return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}

int read()
{
    char c;while(c=tc(),(c<‘0‘||c>‘9‘)&&c!=‘-‘);
    int x=0,y=1;c==‘-‘?y=-1:x=c-‘0‘;
    while(c=tc(),c>=‘0‘&&c<=‘9‘)x=x*10+c-‘0‘;
    return x*y;
}

const int MAXN=10005,MAXM=100005;

int N,M,S,T,x,y,c,ans;
int W[MAXM*2],To[MAXM*2],cnt;
int l[MAXM*5],h,t,dist[MAXN];
vector <int> a[MAXN];

bool BFS()
{
    h=t=0;
    l[++t]=S;
    memset(dist,0,sizeof(dist));dist[S]=1;
        while(h<t){
            int front=l[++h];
                for(int i=0;i<a[front].size();i++){
                    int to=a[front][i];
                    if(!dist[To[to]] && W[to]){
                        dist[To[to]]=dist[front]+1;
                        l[++t]=To[to];
                    }
                }
        }
    return dist[T];
}

int find(int now,int x)
{
    if(now==T) return x;
        for(int i=0;i<a[now].size();i++){
            int to=a[now][i];
            if(dist[To[to]]==dist[now]+1 && W[to]){
                int fd=find(To[to],min(x,W[to]));
                if(fd){
                    W[to]-=fd;
                    W[to^1]+=fd;
                    return fd;
                }
            }
        }
    return 0;
}

int main()
{
    N=read(),M=read(),S=read(),T=read();
        for(int i=1;i<=M;i++){
             x=read(),y=read(),c=read();
             W[cnt]=c,To[cnt]=y;a[x].push_back(cnt);cnt++;
             W[cnt]=0,To[cnt]=x;a[y].push_back(cnt);cnt++;
        }
        while(BFS()){
            ans+=find(S,2e9);
        }
    printf("%d",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Cptraser/p/8283308.html

时间: 2024-10-12 07:49:13

Dinic算法最大流入门的相关文章

POJ1273:Drainage Ditches(最大流入门 EK,dinic算法)

http://poj.org/problem?id=1273 Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer Jo

算法模板——Dinic网络最大流 2

实现功能:同Dinic网络最大流 1 这个新的想法源于Dinic费用流算法... 在费用流算法里面,每次处理一条最短路,是通过spfa的过程中就记录下来,然后顺藤摸瓜处理一路 于是在这个里面我的最大流也采用这种模式,这样子有效避免的递归,防止了爆栈么么哒 1 type 2 point=^node; 3 node=record 4 g,w:longint; 5 next,anti:point; 6 end; 7 var 8 i,j,k,l,m,n,s,t,flow:longint; 9 a,e:a

zoj 3229 dinic算法的非递归实现以及有上下界的有源汇的网络流的最大流的求解

Shoot the Bullet Time Limit: 2 Seconds      Memory Limit: 32768 KB      Special Judge Gensokyo is a world which exists quietly beside ours, separated by a mystical border. It is a utopia where humans and other beings such as fairies, youkai(phantoms)

hiho一下 第119周 #1398 : 网络流五&#183;最大权闭合子图 【最小割-最大流--Ford-Fulkerson 与 Dinic 算法】

#1398 : 网络流五·最大权闭合子图 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 周末,小Hi和小Ho所在的班级决定举行一些班级建设活动. 根据周内的调查结果,小Hi和小Ho一共列出了N项不同的活动(编号1..N),第i项活动能够产生a[i]的活跃值. 班级一共有M名学生(编号1..M),邀请编号为i的同学来参加班级建设活动需要消耗b[i]的活跃值. 每项活动都需要某些学生在场才能够进行,若其中有任意一个学生没有被邀请,这项活动就没有办法进行. 班级建设的活

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

Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 24830   Accepted: 10756 Case Time Limit: 5000MS Description As more and more computers are equipped with dual core CPU, SetagLilb, the Chief Technology Officer of TinySoft C

[POJ 1273]Drainage Ditches(Edmond-Krap算法和Dinic算法求最大流)

自NOIP 2014结束之后将近一个星期没撸题了,现在开始搞省选,发个水水的裸网络流题解吧. 题目链接:http://poj.org/problem?id=1273 裸网络流,模板题. 1.Edmond_Karp算法 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #include <que

HDU ACM 3572 Task Schedule 网络最大流-&gt;dinic算法

分析: 建图:每个任务和每一天分别看做一个点,添加源和汇点.源点和每个任务连一条边,每天边的容量为完成对应任务所需处理次数.若第i个任务能够在Si至Ei天处理,则由该任务向这些天分别连一条边,容量为1,表示此任务每天只能被处理一次.最后,每一天分别连一条边到汇点,容量为机器数M,即每天可以处理M个任务.若求出的最大流等于所有任务需要处理的次数之和,说明能完成任务:否则,不能. #include<iostream> #include<vector> #include<queue

网络最大流 dinic算法

一句话题意:给出一个网络图,以及其源点和汇点,求出其网络最大流 //dinic算法; //时间复杂度O(V^2E); #include<bits/stdc++.h> #define inf 999999 #define maxn 200000 using namespace std; int n,m,s,t; int ans=0; struct Edge { int to,next,w; }; struct Edge edge[maxn]; int head[maxn],val[maxn],p

网络最大流算法—Dinic算法及优化

前置知识 网络最大流入门 前言 Dinic在信息学奥赛中是一种最常用的求网络最大流的算法. 它凭借着思路直观,代码难度小,性能优越等优势,深受广大oier青睐 思想 $Dinic$算法属于增广路算法. 它的核心思想是:对于每一个点,对其所连的边进行增广,在增广的时候,每次增广“极大流” 这里有别于EK算法,EK算法是从边入手,而Dinic算法是从点入手 在增广的时候,对于一个点连出去的边都尝试进行增广,即多路增广 Dinic算法还引入了分层图这一概念,即对于$i$号节点,用$dis(i)$表示它