zoukankan      html  css  js  c++  java
  • 最大流

    最大流最重要的思想就是反向边,其他的不说了,为什么要有反向边呢?

    举个例子,白书上那张图,画一画有奇效。其实每次增广的时候,我们的流到了一个点,然后呢把反向边推回去了,也就是相当于把从那边流过来的流推回去了,为什么这是最优的?你想啊,那个流原来是流向某条边,现在来了一个流,把他替代了,叫这个流回去,当然比以前优了,因为那个流回去之后肯定对答案有贡献。

    bfs是找到下一步往哪里走,也是判断。

    dinic什么分层图不要管他,其实就是每次找自己能走的邻居,只不过是走一步,分层了。

    codevs 1993

    #include<iostream>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int inf=0x3f3f3f3f;
    struct edge
    {
        int to,f,nxt;
    }e[10010];
    int n,m,cnt=1;
    int d[10010],q[10010],g[10010];
    inline void Init()
    {
        memset(d,0x3f3f3f3f,sizeof(d));
        d[1]=1;
    }
    inline void link(int u,int v,int c)
    {
        e[++cnt].nxt=g[u];
        g[u]=cnt;
        e[cnt].to=v;
        e[cnt].f=c;
    }
    inline int Min(int x,int y)
    {
        return x<y?x:y;
    }
    inline int read()
    {
        int x=0,f=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x*=10;x+=c-'0';c=getchar();}
        return x*f;
    }
    bool bfs()
    {
        Init(); 
        queue<int>q;
        q.push(1);
        while(!q.empty())
        {
            int u=q.front(); q.pop();
            for(int i=g[u];i;i=e[i].nxt)
            {
                int v=e[i].to;
                if(e[i].f&&d[v]==inf)
                {
                    d[v]=d[u]+1;
                    q.push(v);
                }
            }
        }    
        return d[n]!=inf;
    }
    int dfs(int u,int delta)
    {
        if(u==n) return delta;
        int ret=0;
        for(int i=g[u];i&&delta;i=e[i].nxt)
        {
            int v=e[i].to;
            if(d[v]==d[u]+1)
            {
                int dd=dfs(v,Min(delta,e[i].f));
                e[i].f-=dd;
                e[i^1].f+=dd;
                delta-=dd;
                ret+=dd;
            }
        }
        return ret;
    }
    inline void dinic()
    {
        int tot=0;
        while(bfs())
        {
            tot+=dfs(1,inf);
        }
        printf("%d",tot);
    }
    int main()
    {
        m=read(); n=read();
        for(int i=1;i<=m;i++)
        {
            int u,v,c; u=read(); v=read(); c=read();
            link(u,v,c); link(v,u,0);
        }
        dinic();
        return 0;
    }
  • 相关阅读:
    需求分析与系统设计(二)阅读笔记
    阅读笔记:需求分析与系统设计(一)
    css方法div固定在网页底部
    阅读笔记:软件需求十步走(三)
    剑指offer 二维数组中的查找
    剑指offer 替换空格
    剑指offer 重建二叉树
    git常用操作
    关于 IO的同步异步间要描述
    svn-代码回滚
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6084007.html
Copyright © 2011-2022 走看看