• 网络流dinic ek模板 poj1273


    这里只是用来存放模板,几乎没有讲解,要看讲解网上应该很多吧……

    ek

    bfs不停寻找增广路到找不到为止,找到终点时用pre回溯,O(VE^2)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int maxn = 205;
    int cap[205][205], pre[205], n, m, a[205];
    int bfs(){
        queue<int> q;
        q.push(1);
        memset(a,0,sizeof(a));
        a[1] = INF;
        while(!q.empty()){
            int front = q.front();
            q.pop();
            for(int i = 1;i<=m;i++){
                if(!a[i] && cap[front][i]){
                    a[i] = min(a[front], cap[front][i]);
                    pre[i] = front;
                    q.push(i);
                }
            }
        }
        return a[m];
    }
    int ek(){
        int ans = 0;
        while(bfs()){
            ans += a[m];
            for(int i = m;i!=1;i = pre[i]){
                cap[pre[i]][i] -= a[m];
                cap[i][pre[i]] += a[m];
            }
        }
        return ans;
    }
    int main(){
        while(~scanf("%d%d",&n,&m)){
            memset(cap,0,sizeof(cap));
            for(int i = 1;i<=n;i++){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                cap[u][v] += w;
            }
            printf("%d
    ",ek());    
        }
        return 0;    
    }

    dinic

    反复构造层次网络加找增广路,优势在于当某点的流入量较大时,可以一次完成多条增广路的累加,O(V^2E)

    记得初始化lv,cnt=1

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int maxn = 205;
    const int INF = 0x3f3f3f3f;
    struct EDGE{
        int to, next, cap, flow;
        EDGE(){}
        EDGE(int a, int b, int c, int d){
            to = a, next = b, cap = c, flow = d;;
        }
    }e[410];
    int head[205], cnt, lv[205],m ,n;
    void add(int from, int to, int cap){
        e[++cnt] = EDGE(to, head[from], cap, 0);
        head[from] = cnt;
        e[++cnt] = EDGE(from, head[to], 0, 0);
        head[to] = cnt;
    }
    int bfs(){
        queue<int> q;
        q.push(1);
        memset(lv,0,sizeof(lv));
        lv[1] = 1;
        while(!q.empty()){
            int front = q.front();
            q.pop();
            for(int i = head[front];i;i = e[i].next){
                int to = e[i].to;
                if(!lv[to] && e[i].cap-e[i].flow){
                    lv[to] = lv[front]+1;
                    q.push(to);
                }
            }
        }
        return lv[m];
    }
    int dfs(int now, int a){
        int flow = 0,f;
        if(now == m) return a;
        for(int i = head[now];i;i = e[i].next){
            int to = e[i].to;
            if(lv[to] == lv[now]+1 && (f = dfs(to,min(a,e[i].cap-e[i].flow)))){
                e[i].flow += f;
                e[i^1].flow -= f;
                flow += f;
                a -= f;
                if(!a) break;
            }
        }
        return flow;
    } 
    int dinic(){
        int ans = 0;
        while(bfs()){
            ans += dfs(1,INF);
        }
        return ans;
    }
    int main(){
        while(~scanf("%d%d",&n,&m)){
            cnt = 1;
            memset(head,0,sizeof(head));
            for(int i = 1;i<=n;i++){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,w);
            }
            printf("%d
    ",dinic());    
        }
        return 0;    
    }
  • 相关阅读:
    常用的 Javascript 操作汇总 (一)
    SQL SERVER 2005 新特性CTE
    屏幕上创建页签
    81条生活小常识大放送 看看哪些你不知道的 生活至上,美容至尚!
    这样保养让你皮肤变水嫩 生活至上,美容至尚!
    头发一周洗几次才适宜? 生活至上,美容至尚!
    人体排毒规律以及排毒食物介绍 生活至上,美容至尚!
    养肝粥,用电脑过度人群必备! 生活至上,美容至尚!
    想睡觉却睡不着,失眠烦恼10招解决 生活至上,美容至尚!
    雪碧的N种新潮喝法雪碧的N种新潮喝法 生活至上,美容至尚!
  • 原文地址:https://www.cnblogs.com/Invisible-full-moon/p/7618511.html
Copyright © 2020-2023  润新知