模板——网络流Dinic

感谢这位大佬的博客:https://www.cnblogs.com/SYCstudio/p/7260613.html 给予了我莫大的帮助!

 

主要说一下网络流的几个注意点:

1.和二分图匹配相似,无法继续增广的网络流即为最大流,但可能因为增广顺序,之前增广的边导致后面更多的边无法增广,所以要允许反悔,即增广之后连反向边

2.因为在增广时可能同一条边来回被增广很多次,所以可能会因为边权差距太大而被卡死,所以要dinic优化分层图查找

3.没有当前弧优化的Dinic是很慢的。。。就是用邻接表记录对于x节点已经“消耗”到哪一条边了

 

废话不多说,附上代码:

#include <bits/stdc++.h>
using namespace std;
const int N=2005;
const int inf=(int)2e9;

int n,m,s,t;
int e,first[N],nxt[N],point[N],w[N],cur[N];
void add(int x,int y,int z)
{
    e++;
    point[e]=y;
    nxt[e]=first[x];
    first[x]=e;
    w[e]=z;
}

void add_edge(int x,int y,int z)
{
    add(x,y,z);
    add(y,x,0);
}

void init()
{
    e=-1;
    memset(first,-1,sizeof(first));
    memset(nxt,-1,sizeof(nxt));
}

int depth[N];
bool bfs()
{
    memset(depth,0,sizeof(depth));
    queue<int> q;
    while(!q.empty()) q.pop();
    q.push(s); depth[s]=1;
    while(!q.empty())
    {
        int u=q.front(); q.pop();
        for(int i=first[u];i!=-1;i=nxt[i])
        {
            int v=point[i];
            if(depth[v]||!w[i]) continue;
            depth[v]=depth[u]+1;
            q.push(v);
        }
    }
    if(depth[t]>0) return 1;
    return 0;
}

int dfs(int u,int flows)
{
    if(u==t) return flows;
    for(int& i=cur[u];i!=-1;i=nxt[i])
    {
        int v=point[i];
        if(w[i]!=0&&depth[v]==depth[u]+1)
        {
            int d=dfs(v,min(w[i],flows));
            if(d)
            {
                w[i]-=d;
                w[i^1]+=d;
                return d;
            }
        }
    }
    return 0;
}

int Dinic()
{
    int ans=0;
    while(bfs())
    {
        for(int i=1;i<=n;i++) cur[i]=first[i];
        while(int d=dfs(s,inf))
        {
            ans+=d;
        }
    }
    return ans;
}

int main() {
    int T; cin>>T;
    for(int iii=1;iii<=T;iii++)
    {
        init();
        scanf("%d%d",&n,&m);
        s=1; t=n;
        for(int i=1;i<=m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add_edge(x,y,z);
        }
        printf("Case %d: %d\n",iii,Dinic());
    }
    return 0;
}
View Code

 

posted @ 2019-07-11 22:13  'Clovers'  阅读(134)  评论(1编辑  收藏  举报