bzoj1070————2016——3——14

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1070;

题目概括:

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

看到这个大概就应该知道是费用流了吧,可是怎么处理一个人等其他人的时间呢? 显然拆点撒,拆T组点,每个人向第j的机器的第z个修的点连一条边,权植为z*time[i][j](为什么是这个呢?

因为你在修的时候别人和你都在等待),所以这道题就这样写完了,但感觉点有点多,所以就写了个(zkw费用流)但是是抄模板的。。。。。醉(好歹有点理解也是好的);

普通费用流也可以过,只不过要小心点.........

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define inf 0x7fffffff
 5 #define maxn 500000
 6 int n,m,tot,s,t,ans;
 7 int pre[maxn],v[maxn],cap[maxn],dis[maxn],sla[maxn],now[maxn],cost[maxn];
 8 int a[100][100];
 9 bool vis[maxn];
10 using namespace std;
11 int num(int i,int j)
12 {
13     return (i*n+j);
14 }
15 void ins(int a,int b, int c, int d)
16 {
17     tot++; pre[tot]=now[a]; now[a]=tot; v[tot]=b; cap[tot]=c; cost[tot]=d;
18 }
19 void insert(int a, int b, int c, int d)
20 {
21     ins(a,b,c,d); ins (b,a,0,-d);
22 }
23 int kk(int x, int f)
24 {
25     int left=f;
26     if (x==t) {ans+=f*dis[s]; return f;
27     }
28     vis[x]=1;
29     for (int i=now[x]; i; i=pre[i])
30     {
31         if (cap[i]>0 && !vis[v[i]])
32         {
33             if (dis[v[i]]+cost[i]-dis[x]==0)
34             {
35                 int delt=kk(v[i],min(cap[i],left));
36                 if (delt>0) cap[i]-=delt,cap[i^1]+=delt,left-=delt;
37                 if (left==0) return f;
38                 
39             }
40             else
41             sla[v[i]]=min(sla[v[i]],dis[v[i]]+cost[i]-dis[x]);
42         }
43     }
44     return (f-left);
45 }
46 bool dfs()
47 {
48     int delt=inf;
49     for (int i=s; i<=t; i++)
50     if (!vis[i]) delt=min(delt,sla[i]),sla[i]=inf;
51     if (delt==inf ) return  true;
52     for (int i=s; i<=t; i++)
53     if (vis[i]) dis[i]+=delt;
54     return false;
55 }
56 void zkw()
57 {
58     for (int i=s; i<=t; i++) dis[i]=0,sla[i]=inf;
59     do{
60         do {memset(vis,0,sizeof(vis));
61         } while(kk(s,inf));
62         
63     }while (!dfs());
64 }
65 int main()
66 {
67     scanf("%d%d",&m,&n);
68     for (int i=1; i <=n; i++) for (int j=1; j<=m; j++) scanf("%d",&a[i][j]);
69     tot=1;
70     s=0; t=n*m+n+1;
71     for (int i=1; i<=n; i++) insert(s,i,1,0);
72     for (int i=1; i<=n; i++)
73         for (int j=1; j<=m; j++)
74             for (int z=1; z<=n; z++)
75             {
76                 insert(i,num(j,z),1,z*a[i][j]);
77             }
78     for (int i=1; i<=m; i++)
79         for (int j=1; j<=n; j++)
80         insert(num(i,j),t,1,0);
81     zkw();
82     printf("%.2lf\n",(1.0*ans)/(1.0*n));     
83 }
View Code

 

posted @ 2016-03-14 19:51  ACist  阅读(347)  评论(0编辑  收藏  举报