最大流模板(Dinic)

最大流模板:

#include<stdio.h>
#include<iostream>
using   namespace std;
const   int oo=1e9;
/**oo 表示无穷大*/
const  int mm=111111111;
/**mm 表示边的最大数量,记住要是原图的两倍,在加边的时候都是双向的*/
const  int mn=999;
/**mn 表示点的最大数量*/
int node,src,dest,edge;
/**node 表示节点数,src 表示源点,dest 表示汇点,edge 统计边数*/
int ver[mm],flow[mm],next[mm];
/**ver 边指向的节点,flow 边的容量 ,next 链表的下一条边*/
int head[mn],work[mn],dis[mn],q[mn];
void prepare(int _node, int _src,int _dest)
{
    node=_node,src=_src,dest=_dest;
    for(int i=0; i<node; ++i)head[i]=-1;
    edge=0;
}
/**增加一条 u 到 v 容量为 c 的边*/
void addedge( int u,  int v,  int c)
{
    ver[edge]=v,flow[edge]=c,next[edge]=head[u],head[u]=edge++;
    ver[edge]=u,flow[edge]=0,next[edge]=head[v],head[v]=edge++;
}
/**广搜计算出每个点与源点的最短距离,如果不能到达汇点说明算法结束*/
bool Dinic_bfs()
{
    int i,u,v,l,r=0;
    for(i=0; i<node; ++i)dis[i]=-1;
    dis[q[r++]=src]=0;
    for(l=0; l<r; ++l)
        for(i=head[u=q[l]]; i>=0; i=next[i])
            if(flow[i]&&dis[v=ver[i]]<0)
            {
                /**这条边必须有剩余容量*/
                dis[q[r++]=v]=dis[u]+1;
                if(v==dest)  return 1;
            }
    return 0;
}
/**寻找可行流的增广路算法,按节点的距离来找,加快速度*/
int Dinic_dfs(  int u, int exp)
{
    if(u==dest)  return exp;
    /**work 是临时链表头,这里用 i 引用它,这样寻找过的边不再寻找*/
    for(  int &i=work[u],v,tmp; i>=0; i=next[i])
        if(flow[i]&&dis[v=ver[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>0)
        {
            flow[i]-=tmp;
            flow[i^1]+=tmp;
            /**正反向边容量改变*/
            return tmp;
        }
    return 0;
}

int Dinic_flow()
{
    int i,ret=0,delta;
    while(Dinic_bfs())
    {
        for(i=0; i<node; ++i)work[i]=head[i];
        while(delta=Dinic_dfs(src,oo))ret+=delta;
    }
    return ret;
}
时间: 2024-11-13 06:17:48

最大流模板(Dinic)的相关文章

Drainage Ditches---hdu1532(最大流, 模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1532 最大流模板题: EK:(复杂度为n*m*m); #include<stdio.h> #include<string.h> #include<queue> #include<algorithm> using namespace std; #define INF 0xfffffff #define N 220 int maps[N][N], pre[N], a

poj1459 Power Network --- 最大流 EK/dinic

求从电站->调度站->消费者的最大流,给出一些边上的容量,和电站和消费者可以输入和输出的最大量. 添加一个超级源点和汇点,建边跑模板就可以了.两个模板逗可以. #include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector&

网路流模板+总结

如此繁复多样的一类问题,就先从模板开始吧 1.最大流算法 模板题:https://www.luogu.org/problemnew/show/P3376 以下所有模板皆以上述问题为准 (1)FF算法(Ford-Fulkerson) 这便是最基础的一种增广路算法. 而所有增广路算法都使用了一种重要的技巧:对所有edge.cap>0的边构造反向边rev(e). 而在我个人看来,构造反向边的精妙之处就在于它使得两个看上去不相干的较难处理的操作化为了一个符合dfs基本法的操作,即所谓的"退流&qu

最大流之dinic

先用bfs预处理出层次图,然后在层次图上用dfs找增广路径,理论复杂度O(n*n*m) const int INF=0xfffffff ; struct node{ int s,t,cap,nxt ; }e[200005] ; int m,n,head[10005],level[10005],cnt ; void add(int s,int t,int cap) { e[cnt].s=s ;e[cnt].t=t ;e[cnt].cap=cap ;e[cnt].nxt=head[s] ;head[

hdu4292 Food 最大流模板题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4292 题意:水和饮料,建图跑最大流模板. 我用的是学长的模板,最然我还没有仔细理解,不过这都不重要直接贴就行了. 下面是AC代码,以后就当做最大流的模板来用了. 代码: #include<cstdio> #include<iostream> using namespace std; const int oo=1e9; const int mm=2e5+5; const int mn=1

POJ2135Farm Tour(最小费用最大流模板)

题目链接:http://poj.org/problem?id=2135 题意:农场主想从1到n,然后从n到1,每条边最多走一次,不能走重复的路,问最短距离是多少. 建图:取超级源点s,并与房子连一条边,容量为2,费用为0:取barn与超级汇点 t 的边的容量为2,费用为0 房子与barn的费用为距离,容量为1 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring>

hdu 3549 Flow Problem(最大流模板题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549 Problem Description Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph. Input The first line of input

[ACM] hdu 3549 Flow Problem (最大流模板题)

Flow Problem Problem Description Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph. Input The first line of input contains an integer T, denoting the nu

POJ3469_Dual Core CPU(网络流/最小割=最大流/模版)----Dinic模版2.0

解题报告 题目传送门 题意: 双核CPU,n个模块,每个模块必须运行在某个CPU核心上,每个模块在cpu单核的消耗A和B,M对模块要共享数据,如果在同一个核心上不用消耗,否则需要耗费.安排N个模块,使得总耗费最小 思路: 将两个cpu核心看成源点和汇点,其他模块分别与源点汇点连线(表示每个模块可以在任意cpu上运行),m对模块分别连双向边,要使得模块只能在一个cpu上运行,就是找到一个割,源点和汇点必不联通,耗费最少就是最小割,最小割最大流原理转换成求最大流. 这题数据大,没优化TLE了,加了两