zoukankan      html  css  js  c++  java
  • ISAP算法(P3376 【模板】网络最大流)

    原题链接:https://www.luogu.org/problem/show?pid=3376

    没什么要说的,这只是一个普通的ISAP板子,只不过用我最喜欢的代码风格重写了一遍。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    void read(int &y)
    {
        y=0;char x=getchar();
        while(x<'0'||x>'9') x=getchar();
        while(x>='0'&&x<='9')
        {
            y=y*10+x-'0';
            x=getchar();
        }
    }
    int min(int x,int y)
    {
        if(x<y) return x;
        else return y;
    }
    struct edge
    {
        int u,v,flow,cap;
    }e[200005];
    int n,m,s,t,cnt;
    int nxt[200005],f[200005];
    int d[10005],par[10005],num[10005],cur[10005],vis[10005];
    void add(int x,int y,int z)
    {
        e[++cnt].u=x;e[cnt].v=y;e[cnt].cap=z;e[cnt].flow=0;
        nxt[cnt]=f[x];f[x]=cnt;
        e[++cnt].u=y;e[cnt].v=x;e[cnt].cap=0;e[cnt].flow=0;
        nxt[cnt]=f[y];f[y]=cnt;
    }
    void bfs()
    {
        queue<int>q;
        vis[t]=1;
        q.push(t);
        while(!q.empty())
        {
            int k=q.front();
            q.pop();
            for(int i=f[k];i;i=nxt[i])
            {
                if(vis[e[i].v]==0&&e[i].cap==0)
                {
                    vis[e[i].v]=1;
                    d[e[i].v]=d[k]+1;
                    q.push(e[i].v);
                }
            }
        }
    }
    int agument()
    {
        int p=t,ans=2147483647;
        while(p!=s)
        {
            ans=min(ans,e[par[p]].cap-e[par[p]].flow);
            p=e[par[p]].u;
        }
        p=t;
        while(p!=s)
        {
            e[par[p]].flow+=ans;
            e[par[p]^1].flow-=ans;
            p=e[par[p]].u;
        }
        return ans;
    }
    int isap()
    {
        int sf=0,p=s;
        for(int i=1;i<=n;i++)
        {
            num[d[i]]++;
            cur[i]=f[i];
        }
        while(d[s]<n)
        {
            if(p==t)
            {
                sf+=agument();
                p=s;
            }
            int flag=0;
            for(int i=cur[p];i;i=nxt[i])
            {
                if(e[i].cap>e[i].flow&&d[p]==d[e[i].v]+1)
                {
                    flag=1;
                    par[e[i].v]=i;
                    cur[p]=i;
                    p=e[i].v;
                    break;
                }
            }
            if(flag==0)
            {
                if(--num[d[p]]==0) break;
                int mn=n-1;
                for(int i=f[p];i;i=nxt[i])
                {
                    if(e[i].cap>e[i].flow) mn=min(mn,d[e[i].v]);
                }
                d[p]=mn+1;
                num[d[p]]++;
                cur[p]=f[p];
                if(p!=s) p=e[par[p]].u;
            }
        }
        return sf;
    }
    int main()
    {
        read(n);read(m);read(s);read(t);
        cnt++;
        for(int i=1;i<=m;i++)
        {
            int a,b,c;
            read(a);read(b);read(c);
            add(a,b,c);
        }
        bfs();
        int ans=isap();
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    C#针对js escape解码
    .NET XML序列化与反序列化
    数据库文档生成工具(1)
    小欣外贸助手-国际站排名查询工具限量封测了
    七夕小福利
    利用正则表达式获取博客园随笔(四)
    利用正则表达式获取博客园随笔
    利用正则表达式获取博客园随笔(三)
    利用正则表达式获取博客园随笔(二)
    利用正则表达式获取博客园随笔(一)
  • 原文地址:https://www.cnblogs.com/zeroform/p/7674443.html
Copyright © 2011-2022 走看看