[BZOJ1070][SCOI2007]修车 费用流
Posted wls001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ1070][SCOI2007]修车 费用流相关的知识,希望对你有一定的参考价值。
1070: [SCOI2007]修车
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 6209 Solved: 2641
[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)
我们先将所有m拆成n个点,每个点表示m倒数第i个维修的车。
对于每一辆车,我们向所有m拆的点连边,容量为1,费用为cost[i][j]*i表示他花的时间和后i个人等待的时间和。
跑最小费用最大流。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #define maxn 700 8 using namespace std; 9 int n,m; 10 int a[100][100]; 11 int t; 12 bool vis[maxn]; 13 int dis[maxn]; 14 struct data { 15 int to,next,c,w; 16 }e[maxn*maxn]; 17 int head[maxn],cnt; 18 int q[maxn]; 19 void add(int u,int v,int w,int c){e[cnt].next=head[u];e[cnt].to=v;e[cnt].c=c;e[cnt].w=w;head[u]=cnt++;} 20 int use=0; 21 bool spfa() { 22 for(int i=0;i<=t;i++) dis[i]=-214748364; 23 memset(vis,0,sizeof(vis)); 24 int h=0,tail=1; 25 q[0]=t; 26 dis[t]=0; 27 vis[t]=1; 28 while(h!=tail) { 29 int now=q[h++];if(h==maxn) h=0; 30 for(int i=head[now];i>=0;i=e[i].next) { 31 int to=e[i].to; 32 if(e[i^1].w>0&&dis[to]<dis[now]+e[i].c) { 33 dis[to]=dis[now]+e[i].c; 34 if(!vis[to]){ 35 vis[to]=1; 36 q[tail++]=to;if(tail==maxn) tail=0; 37 } 38 } 39 } 40 vis[now]=0; 41 } 42 use-=dis[0]; 43 return dis[0]!=-214748364; 44 } 45 int ans=0; 46 int dfs(int now,int af) { 47 if(now==t||af==0){ans+=use*af;return af;} 48 vis[now]=1; 49 int flow=0,f=0; 50 for(int i=head[now];i>=0;i=e[i].next) { 51 int to=e[i].to; 52 if(vis[to]) continue; 53 if(dis[to]==dis[now]+e[i].c&&e[i].w>0&&(f=dfs(to,min(af,e[i].w)))) { 54 e[i].w-=f; 55 e[i^1].w+=f; 56 flow+=f; 57 af-=f; 58 if(!af) break; 59 } 60 } 61 return flow; 62 } 63 void zkw() { 64 while(spfa()) { 65 do { 66 memset(vis,0,sizeof(vis)); 67 }while(dfs(0,2147483647)); 68 memset(vis,0,sizeof(vis)); 69 use=0; 70 } 71 } 72 int main() { 73 memset(head,-1,sizeof(head)); 74 scanf("%d%d",&m,&n); 75 for(int i=1;i<=n;i++) 76 for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); 77 for(int i=1;i<=n;i++) {add(0,i,1,0);add(i,0,0,0);} 78 t=699; 79 for(int i=n+1;i<=n+n*m;i++) {add(i,t,1,0);add(t,i,0,0);} 80 for(int i=1;i<=n;i++) { 81 for(int j=n+1;j<=n+n*m;j++){ 82 int cost=j-n; 83 int temp=cost/n+1; 84 cost%=n; 85 if(!cost) cost=n,temp--; 86 add(i,j,1,a[i][temp]*cost); 87 add(j,i,0,-a[i][temp]*cost); 88 } 89 } 90 zkw(); 91 double ans1; 92 ans1=(double)ans/(double)n; 93 printf("%.2lf",ans1); 94 }
以上是关于[BZOJ1070][SCOI2007]修车 费用流的主要内容,如果未能解决你的问题,请参考以下文章