zoukankan      html  css  js  c++  java
  • 最大流Dinic算法

    摘自大神博客:

    http://www.cnblogs.com/SYCstudio/p/7260613.html


    增广路定理+分层图+当前弧优化

    增广路:从源点出发不停的通过dfs出一条路径到汇点(直到无法走到汇点),每次dfs找出路径中最小残量,回溯时都减掉这个最小残量,并且连一条回边(原因如下图 :)


    分层图:发现增广图处理下图问题非常耗时(s->v->u->t而不是s->v->t),所以每次dfs前都先用bfs求一次深度dep,且dfs时只允许低深度到高深度


    当前弧优化:每次dfs不是从汇点的第一条边开始,而是用cur数组记录u循环到哪条边,以此来加速

    上代码:

    int n, m, s, t;
    struct edge
    {
      int to, w, nx;
    } e[N << 1];
    int fi[N];
    int ce = 1;
    int dep[N];
    bool vis[N];
    int cur[N];
    inline void add(int u, int v, int w)
    {
      e[++ce] = edge{v, w, fi[u]};
      fi[u] = ce;
    }
    int bfs()
    {
      me(dep, 0);
      queue<int> q;
      q.push(s);
      dep[s] = 1;//特别注意这里赋值个不为0的数,不然就是死循环!!!
      while (!q.empty())
      {
        int u = q.front();
        q.pop();
        for (int i = fi[u]; ~i; i = e[i].nx)
        {
          int v = e[i].to;
    
          if (e[i].w && !dep[v])
          {
            dep[v] = dep[u] + 1;
            q.push(v);
          }
        }
      }
      return dep[t];
    }
    int dfs(int u, int flow)
    {
      if (u == t)
        return flow;
      for (int &i = cur[u]; ~i; i = e[i].nx)
      {
        int v = e[i].to;
        if (e[i].w && dep[u] + 1 == dep[v])
        {
          int di = dfs(v, min(e[i].w, flow));
          if (di)
          {
            e[i].w -= di, e[i ^ 1].w += di;
            return di;
          }
        }
      }
      return 0;
    }
    int dinic(int s, int t)
    {
      int res = 0;
      int cnt = 0;
      while (bfs())
      {
        if (++cnt > 20)
          break;
        For(i, 1, n) cur[i] = fi[i];
        while (int di = dfs(s, inf))
          res += di;
      }
      return res;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
      file("test");
    #endif
      me(fi, -1);
      sdf(n), sdf(m), sdf(s), sdf(t);
      while (m--)
      {
        int u, v, w;
        sdf(u), sdf(v), sdf(w);
        add(u, v, w), add(v, u, 0);
      }
      printf("%d", dinic(s, t));
      return 0;
    }
  • 相关阅读:
    课上作业
    大道至简第四章读后感
    课上作业
    读大道至简第三章感想
    关于外部引用JS,中文乱码的问题
    HTML5 之Canvas绘制太阳系
    HTML5 之Canvas 绘制时钟 Demo
    JQuery仿淘宝商家后台管理 之 管理添加分类
    分页存储过程的几种写法
    Javascript-do_while....
  • 原文地址:https://www.cnblogs.com/planche/p/9409473.html
Copyright © 2011-2022 走看看