• 负载平衡问题


    难怪评蓝题,实在是太裸了。

    源点向每个点连边,容量为这个点的现有货物数。

    每个点向汇点连边,容量为要求即sum/n。

    每个点向其相邻两点连边,容量无限,费用为1。

    然后跑一遍源点到汇点的费用流。

    看代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define inf 1e12
    const int maxn=1e5+10;
    int n,a[maxn],sum,ans;
    int beg[maxn],nex[maxn],to[maxn],w[maxn],cost[maxn],e;
    queue<int>q;
    inline int read(){
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        return x*f;
    }
    inline void add(int x,int y,int z,int c){
        nex[e]=beg[x];beg[x]=e;to[e]=y;
        w[e]=z;cost[e]=c;e++;
    }
    int dis[maxn],vis[maxn],las[maxn],ed[maxn],flow[maxn];
    inline int spfa(){
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        dis[0]=0;vis[0]=1;flow[0]=inf;
        las[n+1]=-1;q.push(0);
        while(!q.empty()){
            int x=q.front();
            q.pop();vis[x]=0;
            for(int i=beg[x];~i;i=nex[i]){
                int t=to[i];
                if(w[i]&&dis[t]>dis[x]+cost[i]){
                    dis[t]=dis[x]+cost[i];
                    las[t]=x;ed[t]=i;
                    flow[t]=min(flow[x],w[i]);
                    if(!vis[t]){
                        vis[t]=1;q.push(t);
                    }
                }
            }
        }
        return las[n+1]!=-1;
    }
    signed main(){
        memset(beg,-1,sizeof(beg));
        n=read();
        for(int i=1;i<=n;i++){
            a[i]=read();
            sum+=a[i];
        }
        for(int i=1;i<=n;i++){
            add(0,i,a[i],0);
            add(i,0,0,0);
            add(i,n+1,sum/n,0);
            add(n+1,i,0,0);
            add(i,i%n+1,inf,1);
            add(i%n+1,i,0,-1);
            add(i%n+1,i,inf,1);
            add(i,i%n+1,0,-1);
        }
        while(spfa()){
            ans+=dis[n+1]*flow[n+1];
            int tmp=n+1;
            while(tmp){
                w[ed[tmp]]-=flow[n+1];
                w[ed[tmp]^1]+=flow[n+1];
                tmp=las[tmp]; 
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }

    深深地感到自己的弱小。

  • 相关阅读:
    配置 Linux 服务器 SSH 安全访问的四个小技巧
    线性代数
    转载的其它人博客
    c#下dll引入错误的问题
    游戏中简单代码
    明年的任务
    c# 异步通信网络中存在的问题
    解决导入五万条数据缓慢问题
    c#中关于结构体和字节数组转化
    写给现在的自己
  • 原文地址:https://www.cnblogs.com/syzf2222/p/12669653.html
Copyright © 2020-2023  润新知