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()) ;
    }
    
  • 相关阅读:
    jacman主题分页出现问题(Next<span></span>)
    后会有期(非技术)
    再谈前端性能优化
    emmet常用指令组合
    imagemagick在windows下安装(转,有改动)
    nth-child和蝉原则实现的奇妙随机效果(译)
    flex布局浅谈和实例
    css命名那些事儿
    chrome开发者工具浅析--timeline
    浏览器历史和发展趋势浅析
  • 原文地址:https://www.cnblogs.com/tyqtyq/p/10700819.html
Copyright © 2011-2022 走看看