• [网络流24题-4]负载平衡问题


    负载平衡问题

    又混进来了奇怪的题???我一看这不就是糖果传递???一脸懵逼的我点开题解发现竟然可以MFMC!

    不过糖果传递貌似是这个的加强版(雾)【明明可以线性贪心为什么要网络流!】

    看了一下题解大概是这个样子滴。

    1.相邻的仓库之间连(inf,1)

    2.大于平均值连原点(ai-ave,0)

    3.小于平均值连汇点(ave-ai,0)

    然后跑MFMC就好了啊w

    [写了一堆锅的MCMF...NOIP以后手太生了。。。]

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #define mxn 110
    #define mxm 11000
    #define inf 20021225
    using namespace std;
    
    struct edge{int f,to,lt,c;}e[mxm<<4];
    int in[mxn],s,t,cnt=1,nn,mm,n,m;
    bool vis[mxn];int dis[mxn];
    queue<int> que;
    void addedge(int x,int y,int f,int c)
    {
    	e[++cnt].to=y;e[cnt].lt=in[x];e[cnt].f=f;e[cnt].c=c;in[x]=cnt;
    	e[++cnt].to=x;e[cnt].lt=in[y];e[cnt].f=0;e[cnt].c=-c;in[y]=cnt;
    }
    bool spfa()
    {
    	for(int i=1;i<=nn;i++)	dis[i]=inf,vis[i]=0;
    	while(!que.empty())	que.pop();
    	vis[t]=1;dis[t]=0;que.push(t);
    	while(!que.empty())
    	{
    		int x=que.front();vis[x]=0;que.pop();//printf("QAQ");
    		for(int i=in[x];i;i=e[i].lt)
    		{
    			//printf("*");
    			if(e[i^1].f&&dis[e[i].to]>dis[x]+e[i^1].c)
    			{
    				dis[e[i].to]=dis[x]+e[i^1].c;
    				if(!vis[e[i].to])	que.push(e[i].to),vis[e[i].to]=1;
    			}
    		}
    	}
    	return dis[s]!=inf;
    }
    int ans;
    int dfs(int x,int flow)
    {
    	//printf("QAQ");
    	vis[x]=1;
    	if(x==t||!flow)	return flow;
    	int cur=flow;
    	for(int i=in[x];i;i=e[i].lt)
    	{
    		int v=e[i].to;//printf("*");
    		if(dis[x]==dis[v]+e[i].c&&e[i].f&&!vis[v])
    		{
    			int tmp=dfs(v,min(e[i].f,cur));
    			e[i].f-=tmp;e[i^1].f+=tmp;cur-=tmp;
    			ans+=tmp*e[i].c;
    			if(!cur)	return flow;
    		}
    	}
    	dis[x]=inf;
    	return flow-cur;
    }
    int a[mxn],ave;
    void mcmf()
    {
    	//int w;
    	while(spfa())
    	{
    		//printf("YYY");
    		vis[t]=1;
    		while(vis[t])
    		{
    			memset(vis,0,sizeof(vis));
    			dfs(s,inf);
    		}
    	}
    }
    int main()
    {
    	scanf("%d",&n);
    	s=n+1;t=n+2;nn=t;
    	for(int i=1;i<=n;i++)
    		scanf("%d",&a[i]),ave+=a[i];
    	ave/=n;
    	for(int i=1;i<=n;i++)
    	{
    		if(a[i]>ave)	addedge(s,i,a[i]-ave,0);
    		if(a[i]<ave)	addedge(i,t,ave-a[i],0);
    		if(i==1)	addedge(n,i,inf,1),addedge(i,n,inf,1);
    		else	addedge(i-1,i,inf,1),addedge(i,i-1,inf,1);
    	}
    	mcmf();
    	printf("%d
    ",ans);
    	return 0;
    }
  • 相关阅读:
    Java基础系列1:Java基本类型与封装类型
    深入理解设计模式六大原则
    分布式系统ID生成方案汇总
    微服务入门
    Web攻击技术
    Jedis与Redisson选型对比
    Hystrix分布式系统限流、降级、熔断框架(二)
    可重入锁ReentrantLock实现原理
    Hystrix分布式系统限流、降级、熔断框架(一)
    Redis过期策略、持久化、集群与常见缓存问题
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/10321962.html
Copyright © 2020-2023  润新知