bzoj1070: [SCOI2007]修车
1070: [SCOI2007]修车
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 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
3 2
1 4
Sample Output
1.50
HINT
数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)
Source
一道不错的网络流模型
推荐hzwer 和AaronPolaris的博客
还是强烈推荐画图
容易理解多了
然后记得敲模版要敲对啊
开了防止死循的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; }