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
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 }
我太蒟蒻了,所以神犇们留下意见让我跪膜