Submit: 7014 Solved: 3004
[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)
最小费用最大流
然而bzoj TLE
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 7 const int INF=0x7f7f7f7f; 8 const int N=1005; 9 const int M=100001; 10 const int T=1001; 11 12 struct Edge 13 { 14 int from,to,v,c,next;//from点到to点 v代表容量 c代表花费 next下一条边 15 }E[M]; 16 int node=1; 17 int head[N],from[N],dis[N],vis[N]; 18 19 int n,m; 20 double ans; 21 int t[61][10]; 22 23 void ins(int from,int to,int v,int c) 24 { 25 node++; 26 E[node]=(Edge){from,to,v,c,head[from]}; 27 head[from]=node; 28 } 29 30 void insert(int from,int to,int v,int c) 31 { 32 ins(from,to,v,c);ins(to,from,0,-c); 33 } 34 35 bool spfa() 36 { 37 queue<int> Q; 38 memset(dis,0x7f,sizeof(dis)); 39 Q.push(0);dis[0]=0;vis[0]=1; 40 while(!Q.empty()) 41 { 42 int q=Q.front();Q.pop(); 43 for(int i=head[q];i;i=E[i].next) 44 if(E[i].v>0&&dis[q]+E[i].c<dis[E[i].to]) 45 { 46 dis[E[i].to]=dis[q]+E[i].c; 47 from[E[i].to]=i; 48 if(!vis[E[i].to]) 49 { 50 Q.push(E[i].to); 51 vis[E[i].to]=1; 52 } 53 } 54 vis[q]=0; 55 } 56 return dis[T]!=INF; 57 } 58 59 void mcf() 60 { 61 int x=INF; 62 for(int i=from[T];i;i=from[E[i].from]) 63 x=min(E[i].v,x); 64 for(int i=from[T];i;i=from[E[i].from]) 65 { 66 ans+=x*E[i].c; 67 E[i].v-=x;E[i^1].v+=x; 68 } 69 } 70 71 int main() 72 { 73 scanf("%d %d",&m,&n); 74 for(int i=1;i<=n;i++) 75 for(int j=1;j<=m;j++) 76 scanf("%d",&t[i][j]); 77 for(int i=1;i<=n*m;i++) 78 insert(0,i,1,0); 79 for(int i=n*m+1;i<=n*m+n;i++) 80 insert(i,T,1,0); 81 for(int i=1;i<=m;i++) 82 for(int j=1;j<=n;j++) 83 for(int k=1;k<=n;k++) 84 insert((i-1)*n+j,n*m+k,1,t[k][i]*j); 85 while(spfa()) mcf(); 86 printf("%.2lf",ans/n); 87 return 0; 88 }
显然zkw快的多,正好填了zkw的大坑
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 7 const int INF=0x7f7f7f7f; 8 const int T=1001; 9 10 struct Edge 11 { 12 int from,to,v,c,next; 13 }E[1000000]; 14 int node=1; 15 int head[5000],dis[5000]; 16 bool vis[5000]; 17 18 int n,m; 19 double ans; 20 int t[61][10]; 21 22 void ins(int from,int to,int v,int c) 23 { 24 E[++node]=(Edge){from,to,v,c,head[from]}; 25 head[from]=node; 26 } 27 void insert(int from,int to,int v,int c) 28 { 29 ins(from,to,v,c);ins(to,from,0,-c); 30 } 31 32 bool spfa() 33 { 34 memset(vis,0,sizeof(vis)); 35 memset(dis,0x7f,sizeof(dis)); 36 queue<int> Q; 37 Q.push(T); 38 dis[T]=0;vis[T]=1; 39 while(!Q.empty()) 40 { 41 int q=Q.front();Q.pop(); 42 for(int i=head[q];i;i=E[i].next) 43 if(E[i^1].v&&dis[q]-E[i].c<dis[E[i].to]) 44 { 45 dis[E[i].to]=dis[q]-E[i].c; 46 if(!vis[E[i].to]) 47 { 48 vis[E[i].to]=1; 49 Q.push(E[i].to); 50 } 51 } 52 vis[q]=0; 53 } 54 return dis[0]!=INF; 55 } 56 57 int dfs(int x,int f) 58 { 59 if(x==T) return f; 60 int w,used=0; 61 vis[x]=1; 62 for(int i=head[x];i;i=E[i].next) 63 if(!vis[E[i].to]&&E[i].v&&dis[E[i].to]==dis[x]-E[i].c) 64 { 65 w=f-used; 66 w=dfs(E[i].to,min(w,E[i].v)); 67 ans+=w*E[i].c; 68 E[i].v-=w;E[i^1].v+=w; 69 used+=w; 70 if(used==f) return f; 71 } 72 return used; 73 } 74 75 void zkw() 76 { 77 while(spfa()) 78 { 79 vis[T]=1; 80 while(vis[T]) 81 { 82 memset(vis,0,sizeof(vis)); 83 dfs(0,INF); 84 } 85 } 86 } 87 88 int main() 89 { 90 scanf("%d %d",&m,&n); 91 for(int i=1;i<=n;i++) 92 for(int j=1;j<=m;j++) 93 scanf("%d",&t[i][j]); 94 for(int i=1;i<=n*m;i++) 95 insert(0,i,1,0); 96 for(int i=n*m+1;i<=n*m+n;i++) 97 insert(i,T,1,0); 98 for(int i=1;i<=m;i++) 99 for(int j=1;j<=n;j++) 100 for(int k=1;k<=n;k++) 101 insert((i-1)*n+j,n*m+k,1,t[k][i]*j); 102 zkw(); 103 printf("%.2lf",ans/n); 104 return 0; 105 }