• POJ 3469 /// 最大流Dinic


    题目大意: 

    N个模块 在核A上执行花费a[i] 在核B上执行花费b[i]

    有M个模块组合(d1,d2) 若d1模块与d2模块在不同核上执行需多花费w[i]

    求执行所有模块所需的最小花费

    挑战P237

    将问题转化为最小割问题 求得的最小割就是最小花费

    那么记在核A上执行的模块集合为S 核B上执行的模块集合为T 建立源点s 汇点t 

    某模块在A上执行花费a[i] 则建一条该模块到t容量为a[i]的边

    某模块在B上执行花费b[i] 则建一条s到该模块容量为b[i]的边

    d1模块与d2模块在不同核上执行需多花费w[i] 则建一条d1与d2间容量为w[i]的无向边

    最后求s-t最小割 只要求s到t的最大流就行

    #include <stdio.h>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <queue>
    #define LL long long
    #define INF 0x3f3f3f3f
    using namespace std;
    const int N=2e4+5;
    int n,m,s,t;
    struct NODE { int v,w,r; };
    vector <NODE> E[N];
    void addE(int u,int v,int w) {
        E[u].push_back((NODE){v,w,E[v].size()});
        E[v].push_back((NODE){u,w,E[u].size()-1});
    }
    /**Dinic*/
    int lev[N], cur[N];
    void bfs(int s) {
        queue <int> q;
        memset(lev,-1,sizeof(lev));
        lev[s]=0; q.push(s);
        while(!q.empty()) {
            int u=q.front(); q.pop();
            for(int i=0;i<E[u].size();i++) {
                NODE e=E[u][i];
                if(e.w>0 && lev[e.v]<0) {
                    lev[e.v]=lev[u]+1;
                    q.push(e.v);
                }
            }
        }
    }
    // 广搜一遍把可走的点分层保存在lev[]中
    int dfs(int s,int t,int f) {
        if(s==t) return f;
        // 取地址才能修改到cur[]
        for(int& i=cur[s];i<E[s].size();i++) { 
            NODE& e=E[s][i];
            if(e.w>0 && lev[s]<lev[e.v]) {
                int d=dfs(e.v,t,min(f,e.w));
                if(d>0) {
                    e.w-=d; E[e.v][e.r].w+=d;
                    return d;
                }
            }
        }
        return 0;
    }
    // 深搜找增广路
    int maxFlow(int s,int t) {
        int flow=0;
        while(1) {
            bfs(s);
            if(lev[t]<0) return flow;
            memset(cur,0,sizeof(cur));
            while(1) {
                int f=dfs(s,t,INF);
                if(f==0) break;
                flow+=f;
            }
        } 
    }
    /***/
    
    int main()
    {
        while(~scanf("%d%d",&n,&m)) {
            s=n, t=s+1;
            for(int i=0;i<=t;i++) E[i].clear();
            for(int i=0;i<n;i++) {
                int a,b; scanf("%d%d",&a,&b);
                addE(i,t,a); addE(s,i,b);
            }
            for(int i=0;i<m;i++) {
                int a,b,w; scanf("%d%d%d",&a,&b,&w);
                addE(a-1,b-1,w); addE(b-1,a-1,w);
            }
            printf("%d
    ",maxFlow(s,t));
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    OpenStack开发基础-oslo.config
    对象的封装
    Oracle动态显示日志
    Marching squares &amp; Marching cubes
    Keil5.15使用GCC编译器链接.a库文件
    数据结构习题之树
    HDU 5358(2015多校联合训练赛第六场1006) First One (区间合并+常数优化)
    使用URL在线语音合成
    企业怎样高速搭建大数据处理系统
    http://blog.sina.com.cn/s/blog_7caae74b0100zl17.html
  • 原文地址:https://www.cnblogs.com/zquzjx/p/10153146.html
Copyright © 2020-2023  润新知