最大流的理解以及dinic模板 poj1273

增广路以及残留网络的定义不再赘述了。算导上说的很清楚,证明也有,看懂了就知道怎么求最大流了。

而算导上提到的FF方法以及ek算法的伪代码中都是将流与残留容量分开储存,其实代码实现的时候我们只需存正反向弧的残留容量即可。

然后是对残留网络的一些理解,残留网络中的反向弧是怎么来的?

残留网络的每条边都是这条有向边的残留容量,而残留容量又由公式cf(u,v)=c(u,v)-f(u,v)得到,那么对于一条不存在的有向边(v,u),其容量c(v,u)=0,f(v,u)=-f(u,v)通过反对称性可知,那么这条不存在的有向边的残留容量就等于f(u,v).

而对于(v,u)来说,负的流是允许的,它满足流≤容量的条件。而负的流的含义则是可以压入f(u,v)个单位的流来抵消(u,v)对(v,u)的影响,然后还可压入额外的c(v,u),也就是说一条正向弧的流给反向弧带来的影响是给了反向弧更多的残留容量,甚至是从没有到有,那么这个残留流量的用途就是使流的方向更多样,甚至说它使本来不可以走的路现在变得可以走了,因为你每次找的都是增广路上的最小残留容量,正向弧压入的流给反向弧带来的残留容量,这时就给了你反悔的机会,给运送员带来更多的运送途径来达到最大流的目的。

下面的例子:

在这幅图中我们首先要增广1->2->4->6,这时可以获得一个容量为2的流,但是如果不建立4->2反向弧的话,则无法进一 步增广,最终答案为2,显然是不对的,然而如果建立了反向弧4->2,则第二次能进行 1->3->4->2->5->6的增广,最大流为3.

最后模板:
poj1273
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;

const int maxn=250;

struct node{
    int u,v,next,c;
};
node edge[maxn<<1];
int head[maxn];
int cnt;
int dis[maxn];
int n,m;
int ans;

void init(){
    memset(head,-1,sizeof(head));
    cnt=0;
    memset(dis,-1,sizeof(dis));
    ans=0;
}

void add(int a,int b,int c){
    edge[cnt].u=a;
    edge[cnt].v=b;
    edge[cnt].c=c;
    edge[cnt].next=head[a];
    head[a]=cnt++;
}

int bfs()// 给各点分层,离源点的远近分
{
 memset(dis, -1, sizeof(dis));
 queue<int> q;
 dis[1] = 0;
 q.push(1);
 int i;
 int cur;
 while(!q.empty())
 {
  cur = q.front();
  q.pop();
  for(i = head[cur]; i != -1; i = edge[i].next)
  {
   if(dis[edge[i].v] == -1 && edge[i].c > 0)
   {
    dis[edge[i].v] = dis[cur] + 1;
    q.push(edge[i].v);
   }
  }
 }
 if(dis[m] < 0)
  return 0;
 return 1;
}

int Find(int x,int low){//找增广
    int a;
    if(x==m) return low;
    for(int i=head[x];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(dis[v]==dis[x]+1 && edge[i].c>0 &&(a=Find(v,min(low,edge[i].c))))
        {
            edge[i].c -=a;
            edge[i^1].c +=a;
            return a;
        }
    }
    return 0;
}

void dinic(){
    int temp;
    while(bfs()){
//        printf("%d\n",tmp);
//        if(tmp==0) break;
        temp=Find(1,0x3f3f3f3f);
         ans+=temp;
    }
    printf("%d\n",ans);
}

int main(){
while(~scanf("%d%d",&n,&m)){
    int a,b,flow;
    init();
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&a,&b,&flow);
        add(a,b,flow);
        add(b,a,0);
    }
    dinic();
}
return 0;
}

版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/hitwhacmer1

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

最大流的理解以及dinic模板 poj1273的相关文章

最大流当前弧优化Dinic分层模板

最大流模板: 普通最大流 无向图限制:将无向图的边拆成2条方向相反的边 顶点有流量限制:拆成2个点,连接一条容量为点容量限制的边 无源汇点有最小流限制的最大流:理解为水管流量形成循环,每根水管有流量限制,并且流入量等于流出量 有源汇点的最小流限制的最大流 有最小流量限制的最小流 容量为负数:不能直接利用最大流求边权为负数的最小割.不知道怎么具体处理... 模板使用Dinic分层算法,使用了当前弧优化,效率还是不错的,使用的是vector存图,如果使用邻接表存图效率应该会高一些些吧. 但是ispa

[POJ 1273] Drainage Ditches &amp; 最大流Dinic模板

Drainage Ditches 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 John has built a

洛谷P3376【模板】网络最大流  Dinic模板

之前的Dinic模板照着刘汝佳写的vector然后十分鬼畜跑得奇慢无比,虽然别人这样写也没慢多少但是自己的就是令人捉急. 改成邻接表之后快了三倍,虽然还是比较慢但是自己比较满意了.虽然一开始ecnt从0开始WA了一发... 之前的码风也十分鬼畜呀缩进只缩1.2格不懂自己怎么想的.. 反正今天就安心划划水. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #in

POJ 1273 Drainage Ditches (dinic模板)

题目链接:http://poj.org/problem?id=1273 很经典的最大流问题,用此总结dinic模板 dinic比E-K多了个DFS,只要明白什么是把图分层了,就不难理解了.BFS找增广路的同时把图分层,相当于记录了多条增广路,可以让每次dinic能处理尽量多的增广路. 模板: #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include &

POJ 1273 Drainage Ditches (网络流Dinic模板)

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 John has built a set of drainage

hdu 4289 Control(网络流 最大流+拆点)(模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4289 Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1545    Accepted Submission(s): 677 Problem Description You, the head of Department o

USACO草地排水-网络流dinic模板

广搜计算层次图,在层次图上深搜.标准dinic模板. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<vector> 5 #include<queue> 6 #include<cmath> 7 #include<algorithm> 8 #include<string.h> 9 #define INF 0x7fffff

poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分, dinic

poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分 dinic /* * Author: yew1eb * Created Time: 2014年10月31日 星期五 15时39分22秒 * File Name: poj2391.cpp */ #include <ctime> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring&g

hdu 3277(二分+最大流+拆点+离线处理+模板问题...)

Marriage Match III Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1971    Accepted Submission(s): 583 Problem Description Presumably, you all have known the question of stable marriage match.