码迷,mamicode.com
首页 > 其他好文 > 详细

网络最大流

时间:2020-05-03 15:06:04      阅读:70      评论:0      收藏:0      [点我收藏+]

标签:pac   head   ext   必须   print   clu   不能   没有   bool   

不得不复习一下网络流了,先复习最大流模板吧

最主要的就是dfs和bfs过程吧

bfs是为了分层和判断是否需要继续

显然对于一个图,分层之后,对于任一一边,起点要么加一等于终点,要么终点小于起点

终点小于起点的显然已经计算过,不需要松弛()

判断是否需要继续增广实际上是看终点是否有depth就可以解决的

再说dfs的过程

是通过当前的可以下放的流量dfs下去求得可以达到的流量,回溯上来统计sum,使得始终不超过限制

详细见代码吧,其实复习了一下感觉挺简单的

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>

using namespace std;

struct Edge
{
  int to,val,next;
}e[200010];

int n,m,s,t,num;

int cur[100010],head[100010],depth[100010];

void addedge(int a,int b,int v)
{
  e[num].to=b;
  e[num].next=head[a];
  e[num].val=v;
  head[a]=num++;
}

int dfs(int u,int val)//val是当前可以向前流的流量,返回的是实际流的流量
{
  if(u==t||val==0)//如果到了终点或者没有可以继续的流量了,就return
  {
    return val;
  }
  int sum=0;//分配出去的流量
  for(int &i=cur[u];i!=-1;i=e[i].next)
  {
    if(depth[e[i].to]==depth[u]+1&&e[i].val>0)//分层图下必须要depth向下才进行,不然无意义
    {
      int f=dfs(e[i].to,min(val-sum,e[i].val));//贪心的向下一个点传输可以传输的最大的流量,返回来到底可以传多少就是下一层的事情了
      if(f>0)//如果真的传输过去了,更改当前边和反边
      {
        e[i].val-=f;
        e[i^1].val+=f;
        sum+=f;//记录分配除去的流量
        if(val==sum) return sum;//分配完了就返回
      }
    }
  }
  return sum;//返回实际分配除去的流量
}

bool bfs()//这个函数的意义在于用分层图优化时间,并且预先判断还有没有余留
{
  memset(depth,0,sizeof(depth));//这里一定要memset
  queue <int>q;
  depth[s]=1;
  q.push(s);//塞入起点
  while(!q.empty())
  {
    int now=q.front();
    q.pop();
    for(int i=head[now];i!=-1;i=e[i].next)
    {
      if(depth[e[i].to]==0&&e[i].val>0)//如果没来到过,并且可以流过这个边
      {
        depth[e[i].to]=depth[now]+1;
        q.push(e[i].to);//继续下一层
      }
    }
  }
  return depth[t];//返回是否可以到达t
}

int main()
{
  scanf("%d%d%d%d",&n,&m,&s,&t);
  memset(head,-1,sizeof(head));//毒瘤的反悔边让我改变了码风
  for(int i=1;i<=m;i++)
  {
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    addedge(a,b,c);
    addedge(b,a,0);
  }
  int ans=0;
  while(bfs())
  {
    for(int i=1;i<=n;i++)
    {
      cur[i]=head[i];//清空当前弧,如果是不能跑的边,边权已经是0了,这样反而会漏掉
    }
    ans+=dfs(s,0x3f3f3f3f);
  }
  printf("%d\n",ans);
}

网络最大流

标签:pac   head   ext   必须   print   clu   不能   没有   bool   

原文地址:https://www.cnblogs.com/zzqdeco/p/12821710.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!