【BZOJ2502】清理雪道
【BZOJ1024】【SCOI2009】生日快乐

【BZOJ1070】【SCOI2007】修车

Zarxdy34 posted @ 2015年12月15日 20:56 in BZOJ with tags 网络流 费用流 , 600 阅读

    裸的最小费用最大流。

 

 

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=80,maxm=20,maxv=maxn*maxm,inf=~0U>>1;

int head[maxv],next[maxv*maxn<<1],E[maxv*maxn<<1],F[maxv*maxn<<1],C[maxv*maxn<<1],Ecnt;
int cost[maxm][maxn];
int dis[maxv];
int n,m,s,t;

void Add_Edge(int x,int y,int flow,int c) {next[++Ecnt]=head[x];head[x]=Ecnt;E[Ecnt]=y;F[Ecnt]=0;C[Ecnt]=c;next[++Ecnt]=head[y];head[y]=Ecnt;E[Ecnt]=x;F[Ecnt]=flow;C[Ecnt]=-c;}

int q[maxv],vis[maxv],qhead,qtail;
bool Spfa()
{
	memset(dis,0x7F,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[t]=0;
	qhead=0;qtail=1;
	q[0]=t;vis[t]=1;
	while (qhead!=qtail)
	{
		int x=q[qhead++];
		if (qhead==maxv) qhead=0;
		vis[x]=0;
		for (int i=head[x];i;i=next[i]) if (dis[E[i]]>dis[x]-C[i] && F[i])
		{
			dis[E[i]]=dis[x]-C[i];
			if (!vis[E[i]]) {q[qtail++]=E[i];vis[E[i]]=1;if (qtail==maxv) qtail=0;}
		}
	}
	return dis[s]!=0x7F7F7F7F;
}

int DFS(int x,int flow,int &res)
{
	vis[x]=1;
	if (x==t) return flow;
	int rest=flow;
	for (int i=head[x];i && rest;i=next[i]) if (dis[E[i]]==dis[x]-C[i] && F[i^1] && !vis[E[i]])
	{
		int d=DFS(E[i],min(rest,F[i^1]),res);
		res+=d*C[i];
		rest-=d;F[i]+=d;F[i^1]-=d;
	}
	return flow-rest;
}

int MinCostFlow()
{
	int res=0;
	while (Spfa())
	{
		vis[t]=1;
		while (vis[t])
		{
			memset(vis,0,sizeof(vis));
			DFS(s,inf,res);
		}
	}
	return res;
}

int main()
{
	scanf("%d%d",&m,&n);
	for (int i=1;i<=n;i++)
	for (int j=1;j<=m;j++)
		scanf("%d",&cost[j][i]);
	s=n*m+n+1;t=s+1;Ecnt=1;
	for (int i=1;i<=n;i++)
		Add_Edge(s,n*m+i,1,0);
	for (int i=1;i<=n*m;i++)
		Add_Edge(i,t,1,0);
	for (int i=1;i<=n;i++)
	for (int j=1;j<=m;j++)
	for (int k=1;k<=n;k++)
		Add_Edge(n*m+i,(j-1)*n+k,1,cost[j][i]*k);
	printf("%.2f\n",(double)MinCostFlow()/n);
	return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter