zoukankan      html  css  js  c++  java
  • 洛谷 P4016 负载平衡问题

    题目描述

    (G) 公司有 (n) 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使 (n) 个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。

    输入输出格式

    输入格式:

    文件的第 (1) 行中有 (1) 个正整数 (n),表示有 (n) 个仓库。

    (2) 行中有 (n) 个正整数,表示 (n) 个仓库的库存量。

    输出格式:

    输出最少搬运量。

    输入输出样例

    输入样例#1:

    5
    17 9 14 16 4
    

    输出样例#1:

    11
    

    说明

    (1 leq n leq 100)

    思路:
    1.多于平均值的点由源点建边,他们需要向汇点提供一些物品,流量即为其值减平均值,这里只是声明关系,所以费用为0;反向边正常建立,流量0,费用0。
    2.少于平均值的点向汇点建边,他们需要由源点接收一些物品,流量即为平均值减其值,这里也是声明关系,所以费用为0;反向边正常建立,流量0,费用0。
    3.相邻的点之间 互相建边,如果经过他,代表移动了货物,故需要支出费用的,一单位货物需要一单位费用,所以这些边的费用为1,流量无限制(inf),反向边也是正常建,流量0,费用-1。还有,因为是环所以n和1也要建边。

    代码:

    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<cctype>
    #define inf 0x3f3f3f3f
    #define maxn 100007
    using namespace std;
    int n,S,T,ans,a[1007],head[maxn],num=1,vis[maxn],dis[maxn],from[maxn];
    inline int qread() {
      char c=getchar();int num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';
      return num*f;
    }
    struct node {
      int u,v,f,w,nxt;
    }e[maxn];
    inline void ct(int u, int v, int f, int w) {
      e[++num]=node{u,v,f,w,head[u]};
      head[u]=num;
    }
    int cyh;
    inline bool spfa() {
      memset(dis,inf,sizeof(dis));
      memset(vis,0,sizeof(vis));
      queue<int>q;
      q.push(S),dis[S]=0;
      while(!q.empty()) {
      	int x=q.front();
      	q.pop();vis[x]=0;
      	for(int i=head[x];i;i=e[i].nxt) {
      	  int u=e[i].u,v=e[i].v,f=e[i].f,w=e[i].w;
    	  if(dis[v]>dis[u]+w&&f) {
    		dis[v]=dis[u]+w;
    		from[v]=i;
    		if(!vis[v]) {
    		  vis[v]=1;
    		  q.push(v);
    		}	  
    	  }	
    	}
      }
      return dis[T]!=inf;
    }
    void work() {
      int minn=inf;
      for(int i=T;i!=S;i=e[from[i]].u)
        minn=min(e[from[i]].f,minn);
      for(int i=T;i!=S;i=e[from[i]].u) {
     	e[from[i]].f-=minn;
     	e[from[i]^1].f+=minn;
     	ans+=e[from[i]].w*minn;
      }
    }
    int main() {
      n=qread();
      for(int i=1;i<=n;++i) {
      	a[i]=qread();
      	cyh+=a[i];
      }
      cyh/=n;
      for(int i=1;i<=n;++i) a[i]-=cyh;
      S=0,T=n*n-1;
      for(int i=1;i<=n;++i) {
      	if(a[i]>0) ct(S,i,a[i],0),ct(i,S,0,0);
      	if(a[i]<0) ct(i,T,-a[i],0),ct(T,i,0,0);
      }
      ct(1,2,inf,1),ct(2,1,0,-1),ct(1,n,inf,1),ct(n,1,0,-1);
      for(int i=2;i<n;++i) {
      	ct(i,i+1,inf,1),ct(i+1,i,0,-1);
      	ct(i,i-1,inf,1),ct(i-1,i,0,-1);
      }
      ct(n,1,inf,1),ct(1,n,0,-1),ct(n,n-1,inf,1),ct(n-1,n,0,-1);
      while(spfa()) work();
      printf("%d
    ",ans);
      return 0;
    }
    
  • 相关阅读:
    systemctl无法停掉keepalived
    python小工具
    python pip
    linux下安装python3
    python process
    python socket模块
    python logging日志模块
    板邓:C#的声明数组和赋值
    板邓:解决jquery中全选点击第二次不生效的问题
    板邓:php+mayql分页原理及案例
  • 原文地址:https://www.cnblogs.com/grcyh/p/10804270.html
Copyright © 2011-2022 走看看