bzoj1070: [SCOI2007]修车


1070: [SCOI2007]修车

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 5817  Solved: 2466
[Submit][Status][Discuss]

Description

  同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同
的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最
小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。

Input

  第一行有两个m,n,表示技术人员数与顾客数。 接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人
员维修第i辆车需要用的时间T。

Output

  最小平均等待时间,答案精确到小数点后2位。

Sample Input

2 2
3 2
1 4

Sample Output

1.50

HINT

数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)

Source


一道不错的网络流模型

推荐hzwerAaronPolaris的博客

还是强烈推荐画图

容易理解多了

然后记得敲模版要敲对

开了防止死循的visit数组

然后忘记用啊忘记用啊忘记用啊

然后一直RE ,一直开大数组

直到师兄提醒了一句查模版

扫了一眼就发现了忘记if了

有毒啊

#include<cstdio>
#include<iostream>
#include<cstring>
const int N=1005,M=50005*2,len=1e5,inf=0x3f3f3f3f;
struct node
{
	int v,c,next,to;
}e[M];
int cnt=1,s,t;int first[N],T[61][11];
int dis[N],qu[len],visit[N],cur[N];
int ans=0;
void insert(int u,int v,int q,int c)
{
	e[++cnt].to=v;e[cnt].next=first[u];first[u]=cnt;e[cnt].v=q;e[cnt].c=c;
	e[++cnt].to=u;e[cnt].next=first[v];first[v]=cnt;e[cnt].v=0;e[cnt].c=-c;
//	printf("%d %d %d %d\n",u,v,q,c);
}
bool spfa()
{
	memset(dis,inf,4*(t+5));
	int i=1,j=2;
	qu[1]=s;visit[s]=1;dis[s]=0;
	while(i!=j)
	{
		int r=qu[i++];if(i==len)	i=0;
		for(int k=first[r];k;k=e[k].next)
		if(e[k].v>0&&dis[e[k].to]>dis[r]+e[k].c)
		{
			dis[e[k].to]=dis[r]+e[k].c;
			if(!visit[e[k].to])
			{
				visit[e[k].to]=1;
				if(dis[e[k].to]<dis[qu[i]])
				{
					i--;
					if(i<0)	i=len-1;
					qu[i]=e[k].to;
				}
				else 
				{
					qu[j++]=e[k].to;if(j==len)	j=0;
				}
			}
		}
		visit[r]=0;
	}
	return dis[t]==inf?0:1;
}
int dfs(int x,int a)
{
	if(x==t||!a)	return a;
	visit[x]=1;
	int flow=0,w;
	for(int &k=cur[x];k;k=e[k].next)
	if(!visit[e[k].to]&&e[k].v>0&&dis[e[k].to]==dis[x]+e[k].c&&(w=dfs(e[k].to,std::min(e[k].v,a) ) )>0)
	{
		e[k].v-=w;e[k^1].v+=w;
		ans+=e[k].c*w;
		a-=w;flow+=w;
		if(!a)	break;
	}
	visit[x]=0;
	return flow;
}
int main()
{
	int n,m;//n车 m技术人员 
	scanf("%d %d",&m,&n);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	scanf("%d",&T[i][j]);
	
	t=m*n+n+1;
	
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	for(int k=1;k<=n;k++)
	insert(i,j*n+k,1,T[i][j]*k);
	
	for(int i=1;i<=n;i++)	insert(s,i,1,0);
	
	for(int j=1;j<=m;j++)
	for(int k=1;k<=n;k++)
	insert(j*n+k,t,1,0);
	
	while(spfa())
	{
		for(int i=s;i<=t;i++)	cur[i]=first[i];
		dfs(s,inf);
	}
	printf("%.2lf\n",(double)ans*1.0/n);
	return 0;
}





posted @ 2017-06-29 18:32  Brian551  阅读(98)  评论(0编辑  收藏  举报