bzoj1070[SCOI2007]修车
1070: [SCOI2007]修车
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 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
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 }