zoukankan      html  css  js  c++  java
  • Dinic学习笔记

    网络流是啥不用我说了吧

    增广路定理不用我说了吧

    Dinic就是分层然后只在层间转移,然后就特别快,$$O(N^2M)$$

    伪代码:

    function dinic
        int flow = 0 ;
        while bfs() do
            memsets()
            while int val = dfs() do
                flow += val;
        return flow
    
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std ;
    #define MAXN 1000005
    
    int head[MAXN],ver[MAXN*4],edge[MAXN*4],Next[MAXN*4],tot=-1,s,t ;
    int dep[MAXN],cur[MAXN] ;
    int n,m ;
    void init(){
        tot = -1 , memset(head,-1,sizeof(head)),memset(Next,-1,sizeof(Next)) ;
    }
    void _add(int u,int v,int w){
        ver[++tot]=v,
        edge[tot]=w,
        Next[tot]=head[u],
        head[u]=tot ;
    }
    void add(int u,int v,int w){
        _add(u,v,w),
        _add(v,u,0) ;
    }
    int bfs(){
        memset(dep,0,sizeof(dep)) ;
        queue<int> Q ;while(!Q.empty()) Q.pop() ;
        Q.push(s) ; dep[s] = 1 ;
        while(!Q.empty()){
            
            int v=Q.front() ; Q.pop() ; 
            for(int i=head[v];i!=-1;i=Next[i]){
                //printf("Bfs: at dot %d
    ",ver[i]) ;
                //for(int j=1;j<=MAXN*10;++j) ;
                if(dep[ver[i]] == 0 && edge[i]>0) 
                    dep[ver[i]] = dep[v]+1 , Q.push(ver[i]) ;
            }
        }
        if(!dep[t]) return 0 ;
        return 1 ;
    }
    int dfs(int u,int f){
        if(u == t) return f ;
        for(int& i=cur[u];i!=-1;i=Next[i]){
            if(dep[ver[i]] == dep[u]+1 && edge[i]!=0){	
                int di = dfs(ver[i],min(edge[i],f)) ;
                if(di > 0){
                    edge[i] -= di , edge[i^1] += di ;
                    return di ;
                }
            }
        }
        return 0 ;
    }
    int Dinic(){
        int flow = 0 , d = 0 ;
        while(bfs()){
            for(int i=1;i<=n;++i) cur[i] = head[i] ;
            while(d = dfs(s,0x3f3f3f3f)) flow += d ;
        }
        return flow ;
    }
    int main(){
        init() ;
        scanf("%d%d%d%d",&n,&m,&s,&t) ;
        for(int i=1;i<=m;++i){
            int x,y,z ; scanf("%d%d%d",&x,&y,&z) ; add(x,y,z) ;
        }
        printf("%d
    ",Dinic()) ;
    }
    
  • 相关阅读:
    通过git向github提交项目
    git连接github mac
    char如何储存3个字节或者4个字节
    centOS 7安装jdk
    在移动端语言react中使用video.js
    小程序自定义头部navbar组件
    git常用指令汇总学习
    react表单
    react从入门到熟悉(回顾react)
    react生命周期
  • 原文地址:https://www.cnblogs.com/tyqtyq/p/10700819.html
Copyright © 2011-2022 走看看