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

    题目大意

    一个环上有(n)个仓库,每个仓库存储的货物数量不等,如何用最少搬运量可以使 (n) 个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。

    P4016 负载平衡问题

    问题解决

    貌似这个就是一道奥数题,但是众所周知,(OI)不是(MO)我们考虑用(OI)的方法来解决

    每个点中的货物运输很难处理,但是总的数是不变的,而且(n)非常小,我们就可以考虑用费用流来解决这个问题

    我们先算出最终状态,也就是(avg= sum /n)

    • 建立一个超级原点,和超级汇点

    • 对于一个(a[i]-avg>0)的仓库,也就是说需要将货物从这里运走,所以从超级原点建一条到(a[i])的边,流量为(a[i]-avg),费用为(0)

    • 对于一个(a[i]-avg<0)的仓库,也就是说需要货物运进来,所以建一条从(a[i])到超级汇点的边,流量为(a[i]-avg),费用为(0)

    • (a[i])之间可以相互运,所以之间建一条边,流量为(INF),费用为(1),注意是环

    代码实现

    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int maxn=105,maxe=605,INF=0x3f3f3f3f;
    int N,avg,a[maxn],Ans;
    int lnk[maxn],nxt[maxe],son[maxe],w[maxe],c[maxe],cnt=1,st,ed,x[maxn];
    int dis[maxn],vis[maxn];
    int mincost;
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    void add_e(int x,int y,int z,int cost){son[++cnt]=y;w[cnt]=z;c[cnt]=cost;nxt[cnt]=lnk[x];lnk[x]=cnt;}
    void add_edge(int x,int y,int z,int cost){add_e(x,y,z,cost);add_e(y,x,0,-cost);}
    int spfa(){
    	queue<int> q;
    	memset(dis,INF,sizeof dis);
    	memset(vis,0,sizeof vis);
    	dis[st]=0;q.push(st);
    	while(!q.empty()){
    		int cur=q.front();q.pop();vis[cur]=0;
    		for(int j=lnk[cur];j;j=nxt[j]){
    			if(w[j]>0&&dis[son[j]]>dis[cur]+c[j]){
    				dis[son[j]]=dis[cur]+c[j];
    				if(!vis[son[j]]){vis[son[j]]=1;q.push(son[j]);}
    			}
    		}
    	}
    	return dis[ed]!=INF;
    }
    int DFS(int x,int delta){
    	if(x==ed)return delta;
    	vis[x]=1;int flow=0;
    	for(int j=lnk[x];j;j=nxt[j]){
    		if(!vis[son[j]]&&w[j]>0&&dis[son[j]]==dis[x]+c[j]){
    			int tmp=DFS(son[j],min(delta-flow,w[j]));
    			if(tmp){
    				mincost+=(c[j]*tmp);
    				w[j]-=tmp;w[j^1]+=tmp;flow+=tmp;
    			}
    		}
    	}
    	vis[x]=0;
    	return flow;
    }
    int Dinic(){
    	int maxflow=0;
    	while(spfa()){
    		while(1){
    			int temp=DFS(st,INF);
    			if(!temp)break;
    			maxflow+=temp;
    		}
    	}
    	return maxflow;
    }
    int main(){
    	N=read();for(int i=1;i<=N;i++) a[i]=read(),avg+=a[i];avg/=N;
    	st=0;ed=N+1;
    	for(int i=1;i<=N;i++){x[i]=a[i]-avg;if(x[i]>0)add_edge(st,i,x[i],0);if(x[i]<0)add_edge(i,ed,-x[i],0);}
    	for(int i=1;i<=N;i++){if(i!=1)add_edge(i,i-1,INF,1);if(i!=N)add_edge(i,i+1,INF,1);}
    	add_edge(1,N,INF,1);add_edge(N,1,INF,1);
    	Ans=Dinic();
    	printf("%d
    ",mincost);
    	return 0;
    }
    
  • 相关阅读:
    ubuntu下无法在目录下创建文件夹,权限不足解决办法
    mongo中的模糊查询
    mysql中的模糊查询
    mysql安装与配置详情
    Django model中的class Meta详解
    kafka集群搭建
    myeclipse/eclipse添加Spket插件实现ExtJs4.2/ExtJs3智能提示
    博客园自定义标题、阅读目录、导航栏、活动的推荐&反对按钮
    IntelliJ IDEA 14 创建maven项目二
    EXT4.2--Ext Designer 使用
  • 原文地址:https://www.cnblogs.com/martian148/p/15180117.html
Copyright © 2011-2022 走看看