bzoj1070[SCOI2007]修车

1070: [SCOI2007]修车

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 4706  Solved: 1931
[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

Sample Output

1.50

HINT

数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)

 
这题我不会写TAT
以下是黄学长的题解

N辆车,M个工人。

把每个工人拆成N个点。记为A[i,j]表示第i个工人修倒数第j辆车。

每个车跟所有N*M个工人拆出的点连边。流量为1,费用为time[i,j]*k。

源和每辆车连边,N*M个点和汇连边,流量都为1,费用同为0。

为什么这么构图呢? 

考虑第i个工人,他修第j辆车只对后面要修的车有影响,而前面修过的车已经对当前没有影响了。

而这个影响就是后面每个将要修理的车都多等待了time的时间。

其他边流量都为1是显然的,每辆车修一次,每个工人一个时段只能修理一辆车。

 1 #include<bits/stdc++.h>
 2 #define rep(i,l,r) for(int i=l;i<=r;i++) 
 3 #define inf 214748363
 4 #define N 1000
 5 using namespace std;
 6 struct Edge{
 7     int to,next,from,c,w;
 8 }e[100000];
 9 int head[N],tot=1,ans,dis[N],from[N],r[N],i,n,p,T,tott,num[100][100],mp[100][100],m;
10 bool used[N];
11 inline void ins(int u,int v,int w,int cost) {
12      e[++tot].to=v; e[tot].next=head[u]; head[u]=tot; e[tot].w=w; e[tot].c=cost; e[tot].from=u;
13 }
14 inline void insert(int u,int v,int w,int cost) {
15      ins(u,v,w,cost); ins(v,u,0,-cost);
16 }
17 inline bool spfa() {
18      queue<int> q; for(int i=0;i<=T;i++) dis[i]=inf; dis[0]=0; q.push(0); used[0]=1;  
19      while(!q.empty()) {
20           int x=q.front(); q.pop();
21           for(int k=head[x];k;k=e[k].next) 
22            if(e[k].w>0&&dis[x]+e[k].c<dis[e[k].to]){
23                   dis[e[k].to]=dis[x]+e[k].c; from[e[k].to]=k;
24                   if(!used[e[k].to]) {
25                         used[e[k].to]=1; q.push(e[k].to);
26                   }
27             }
28            used[x]=0;
29      }
30      if(dis[T]==inf) return 0;else return 1;
31 }
32 
33 inline void run() {
34      int x=inf;
35      for(int k=from[T];k;k=from[e[k].from]) x=min(x,e[k].w);
36      for(int k=from[T];k;k=from[e[k].from]) {
37           e[k].w-=x; e[k^1].w+=x; ans+=e[k].c*x;
38      }
39 }
40 
41 inline int read() {
42     int x=0; char ch=getchar();
43     while(ch<'0' || ch>'9') ch=getchar();
44     while(ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
45     return x;
46 }
47 int main ()  {
48       m=read() ; n=read();
49       rep(i,1,n)  rep(j,1,m) mp[i][j]=read();
50       rep(i,1,n) insert(0,i,1,0);
51       int tott=n;
52       rep(i,1,m) rep(j,1,n)  num[i][j]=++tott;
53       T=tott+1;
54       rep(i,1,n)
55         rep(j,1,m)
56           rep(k,1,n)  insert(i,num[j][k],1,mp[i][j]*k);
57       rep(i,1,m) rep(j,1,n) insert(num[i][j],T,1,0);
58       while(spfa()) run() ;
59       printf("%.2lf",(double)ans/n);
60       return  0;
61 }
View Code
原文地址:https://www.cnblogs.com/Bloodline/p/5886302.html