bzoj1070: [SCOI2007]修车
程序员文章站
2022-07-14 18:26:42
...
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;
}
上一篇: 随机森林
下一篇: react中export等区别