zoukankan      html  css  js  c++  java
  • LOJ6013 负载平衡 [最小费用最大流]

    负载平衡

    题目描述见链接 .


    color{red}{正解部分}

    将仓库分为两个类型, 第一个类型为稀缺货物的仓库 {ai}{a_i}, aia_i平均值xix_i,
    第二个类型为富余货物的仓库 {bi}{b_i}, bib_i平均值yiy_i,

    然后建立 超级源点 SS超级汇点 TT,

    • SSaia_i费用00, 容量xIx_I 的边 .
    • bib_iTT费用00, 容量yiy_i 的边 .
    • 相邻的仓库连 费用11, 容量infinf无向边 .

    color{red}{实现部分}

    #include<bits/stdc++.h>
    #define reg register
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 505;
    const int inf = 0x3f3f3f3f;
    const int S = 101, T = 102;
    
    int N;
    int Ans;
    int num0;
    int Tmp_1;
    int A[maxn];
    int Dis[maxn];
    int head[maxn];
    int Pre[maxn][2];
    
    bool vis[maxn];
    
    struct Edge{ int nxt, to, w, c, f; } edge[maxn << 2];
    
    void Add(int from, int to, int w, int cup, int flow){ 
            edge[++ num0] = (Edge){ head[from], to, w, cup, flow };
            head[from] = num0;
    }
    
    bool spfa(){
            memset(Dis, 0x3f, sizeof Dis);
            std::queue <int> Q; Q.push(S); Dis[S] = 0;
            while(!Q.empty()){
                    int ft = Q.front(); Q.pop(); vis[ft] = 0;
                    for(reg int i = head[ft]; i; i = edge[i].nxt){
                            int to = edge[i].to;
                            if(Dis[to] > Dis[ft] + edge[i].w && edge[i].c > edge[i].f){
                                    Dis[to] = Dis[ft] + edge[i].w;
                                    Pre[to][0] = ft, Pre[to][1] = i;
                                    if(!vis[to]) vis[to] = 1, Q.push(to);
                            }
                    }
            }
            return Dis[T] != inf;
    }
    
    void Mmflow(){
            while(spfa()){
                    int t = T, mf = inf;
                    while(t != S){
                            int id = Pre[t][1];
                            mf = std::min(mf, edge[id].c-edge[id].f);
                            t = Pre[t][0];
                    }
                    Ans += mf * Dis[T], t = T;
                    while(t != S){
                            int id = Pre[t][1];
                            edge[id].f += mf, edge[id^1].f -= mf;
                            t = Pre[t][0];
                    }
            }
    }
    
    int main(){
            N = read();
            for(reg int i = 1; i <= N; i ++) Tmp_1 += (A[i] = read());
            Tmp_1 /= N, num0 = 1;
            for(reg int i = 1; i <= N; i ++){
                    if(A[i] > Tmp_1) Add(S, i, 0, A[i]-Tmp_1, 0), Add(i, S, 0, 0, 0);
                    else if(A[i] < Tmp_1) Add(i, T, 0, Tmp_1-A[i], 0), Add(T, i, 0, 0, 0);
            }
            for(reg int i = 1; i <= N; i ++){
                    if(i != 1) Add(i, i-1, 1, inf, 0), Add(i-1, i, -1, 0, 0);
                    if(i != N) Add(i, i+1, 1, inf, 0), Add(i+1, i, -1, 0, 0);
            }
            Add(1, N, 1, inf, 0), Add(N, 1, -1, 0, 0);
            Add(N, 1, 1, inf, 0), Add(1, N, -1, 0, 0);
            Mmflow();
            printf("%d
    ", Ans);
            return 0;
    }
    
  • 相关阅读:
    wnmpa或lnmpa 服务器搭建和原理
    windows 桌面图标 隐藏 小盾牌标志
    C# 执行 CMD 终极稳定解决方案
    比较两个object是否相等
    Microsoft Store 加载失败
    ORA-12514: TNS:监听程序当前无法识别连接描述符中请求的服务
    Win10安装gcc、g++、make
    通过proxifier实现酸酸乳全局代理
    C# 字母转数字
    html中设置锚点定位的几种常见方法(#号定位)
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822445.html
Copyright © 2011-2022 走看看