【最大流】Dinic

★推荐:Dinic入门

本质:网络流本质上是为了解决一类取舍问题,这类取舍问题无法得知最优策略的模式(无法DP),因此通过构造一些带容量的路径表示原题目容量,模拟水流在这些容量之间的取舍,从而可以利用网络流来解决取舍问题。

Dinic算法:bfs得到分层图,然后严格按照分层图寻找增广路,重复至S-T断路。

当前弧优化:DFS过程中访问x点时一旦流入量=流出量就退出,记录下此时正在考虑的弧(当前弧),下次从此处继续考虑即可。

当前弧之前的弧,不能使流入量-流出量=0,那么一定该弧以及该弧之后的弧中有断裂,那么下次再考虑就没有意义了。

当前弧本身,使流入量-流出量=0,也就是使该点前面的弧中最小的一条断裂了,当前弧以及当前弧连出去之后的弧只是有可能断裂,那么下次就应该从这条当前弧开始考虑。

写Dinic一定要加当前弧优化,效果显著。

反向弧:大多数时候反向弧并不影响算法正确性,所以不要考虑以免造成混乱。

反向弧的意义推荐这篇博客

反向弧就是给程序提供反悔的机会,流过反向弧x'相当于帮原来的x流完剩余的路程,而让x不流过来改去别的地方。

复杂度:O(n^2*m)

注意:tot=1

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,S,T;
namespace nwf{
    const int maxn=210,maxm=210,inf=0x3f3f3f3f;
    int tot=1,first[maxn],d[maxn],q[maxn],cur[maxn];
    struct edge{int v,f,from;}e[maxm*2];
    void insert(int u,int v,int f){
        tot++;e[tot].v=v;e[tot].f=f;e[tot].from=first[u];first[u]=tot;
        tot++;e[tot].v=u;e[tot].f=0;e[tot].from=first[v];first[v]=tot;
    }
    bool bfs(){
        memset(d,-1,sizeof(d));
        d[S]=0;
        int head=0,tail=1;q[head]=S;
        while(head<tail){
            int x=q[head++];
            for(int i=first[x];i;i=e[i].from)if(e[i].f&&d[e[i].v]==-1){
                d[e[i].v]=d[x]+1;
                q[tail++]=e[i].v;
            }
        }
        return ~d[T];
    }
    int dfs(int x,int a){
        if(x==T||a==0)return a;
        int flow=0,f;
        for(int& i=cur[x];i;i=e[i].from)
        if(e[i].f&&d[e[i].v]==d[x]+1&&(f=dfs(e[i].v,min(a,e[i].f)))){
            e[i].f-=f;e[i^1].f+=f;
            flow+=f;a-=f;
            if(a==0)break;
        }
        return flow;
    }
    int dinic(){
        int ans=0;
        while(bfs()){
            for(int i=S;i<=T;i++)cur[i]=first[i];
            ans+=dfs(S,inf);
        }
        return ans;
    }
}
int main(){
    scanf("%d%d",&m,&n);
    for(int i=1;i<=m;i++){
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        nwf::insert(u,v,w);
    }
    S=1;T=n;
    printf("%d",nwf::dinic());
    return 0;
}
View Code

相关文章:

  • 2021-10-12
  • 2021-10-23
  • 2022-01-31
猜你喜欢
  • 2021-10-05
  • 2022-12-23
  • 2022-12-23
  • 2021-08-31
  • 2022-12-23
  • 2021-11-12
  • 2021-07-11
相关资源
相似解决方案