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

负载平衡问题

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

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

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

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

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

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

然后跑MFMC就好了啊w

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

#include
#include
#include
#include
#include
#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 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]

你可能感兴趣的:(题解,————图论————,网络流)