zoukankan      html  css  js  c++  java
  • P4016 负载平衡问题 网络流重温

    P4016 负载平衡问题

    这个题目现在第二次做,感觉没有这么简单,可能是我太久没有写这种题目了,基本上都忘记了,所以我连这个是费用流都没有看出来。

    有点小伤心,知道是费用流之后,我居然还拆点了。

    这个写完之后确实感觉没有那么难,但是写的过程还是很艰辛的,这个为什么是一个费用流呢,

    因为我们知道每移动一个单位的货物,就会产生一单位的费用,所以这个就是费用流。

    再而为什么这个不要拆点呢,因为每一个点都是只有一种属性,要么就是多了要输出,要么就是少了要进入,这个其实我也有点不是很清楚。

    还没有完全弄明白。

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <iostream>
    #include <vector>
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn = 3e5 + 10;
    typedef long long ll;
    struct edge
    {
        int u, v, c, f, cost;
        edge(int u=0,int v=0,int c=0,int f=0,int cost=0):u(u),v(v),c(c),f(f),cost(cost){}
    };
    vector<edge>e;
    vector<int>G[maxn];
    int a[maxn], p[maxn], inq[maxn], d[maxn], n, m;
    void init(int n)
    {
        for (int i = 0; i <= n; i++) G[i].clear();
        e.clear();
    }
    void addedge(int u,int v,int c,int cost)
    {
        e.push_back(edge(u, v, c, 0, cost));
        e.push_back(edge(v, u, 0, 0, -cost));
        int m = e.size();
        G[u].push_back(m - 2);
        G[v].push_back(m - 1);
    }
    bool spfa(int s,int t,int &flow,ll &cost)
    {
        memset(d, inf, sizeof(d));
        memset(inq, 0, sizeof(inq));
        d[s] = 0, inq[s] = 1;
        p[s] = 0, a[s] = inf;
        queue<int>que;
        que.push(s);
        while(!que.empty())
        {
            int u = que.front(); que.pop();
            inq[u] = 0;
            for(int i=0;i<G[u].size();i++)
            {
                edge &now = e[G[u][i]];
                int v = now.v;
                if(now.c>now.f&&d[v]>d[u]+now.cost)
                {
                    d[v] = d[u] + now.cost;
                    p[v] = G[u][i];
                    a[v] = min(a[u], now.c - now.f);
                    if (!inq[v]) que.push(v), inq[v] = 1;
                }
            }
        }
        if (d[t] == inf) return false;
        flow += a[t];
        cost += d[t] * 1ll * a[t];
        for(int u=t;u!=s;u=e[p[u]].u)
        {
            e[p[u]].f += a[t];
            e[p[u] ^ 1].f -= a[t];
        }
        return true;
    }
    
    int MincostMaxflow(int s,int t,ll &cost)
    {
        cost = 0;
        int flow = 0;
        while (spfa(s, t, flow, cost));
        return flow;
    }
    
    int main() {
        int n, sum = 0;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]), sum += a[i];
        sum /= n;
        int s = 0, t = n + 1;
        for(int i=1;i<=n;i++)
        {
            if (a[i] > sum) addedge(s, i, a[i] - sum, 0);
            else addedge(i, t, sum - a[i], 0);
            if(i==1)
            {
                addedge(1, 2, inf, 1);
                addedge(1, n, inf, 1);
            }
            else if(i==n)
            {
                addedge(n, 1, inf, 1);
                addedge(n, n - 1, inf, 1);
            }
            else
            {
                addedge(i, i + 1, inf, 1);
                addedge(i, i - 1, inf, 1);
            }
        }
        ll ans = 0;
        MincostMaxflow(s, t, ans);
        printf("%lld
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    bzoj 3243: [Noi2013]向量内积
    bzoj 4818: [Sdoi2017]序列计数
    AtCoder Grand Contest 023 F
    bzoj 4573: [Zjoi2016]大森林
    bzoj 5305: [Haoi2018]苹果树
    bzoj 5298: [Cqoi2018]交错序列
    codeforces496C
    codeforces534B
    牛客小白月赛13
    codeforces605A
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/11232013.html
Copyright © 2011-2022 走看看