bzoj 1070修车
1070: [SCOI2007]修车
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3865 Solved: 1581
[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)
最小费用最大流
时间的先后不好维护怎么办,讲工人拆成n个点,每个点表示第几个修当前这辆车。考虑第i个工人,他修第j辆车只对后面要修的车有影响,而前面修过的车已经对当前没有影响了
所以只需要将费用乘以k。然后每辆车向每个工人的每个点连费用不同的边,就可以轻松解决时间先后关系的问题。
方法:时间先后对费用有影响,将时间拆出来,分别考虑,讨论当前次序的费用,可以解决时间或次序的先后问题
注意:不要把n,m读反
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 1020
#define maxm 100020
#define inf 0x3f3f3f3f
struct node{
int to,next,f,ct,from;
}e[maxm * 2];
int head[maxn],cnt = 1,maxflow,mincost,dis[maxn],src,sink;
int q[maxn * 10],hh,tt,inq[maxn],prev[maxn];
int n,m;
int _time[100][100];
double ans;
inline void adde(int x,int y,int c,int ct){
e[++cnt].to = y;
e[cnt].from = x;
e[cnt].next = head[x];
e[cnt].f = c;
e[cnt].ct = ct;
head[x] = cnt;
e[++cnt].to = x;
e[cnt].from = y;
e[cnt].next = head[y];
e[cnt].f = 0;
e[cnt].ct = -ct;
head[y] = cnt;
}
inline bool spfa(){
memset(dis,0x3f,sizeof(dis));
tt = hh = 0;
q[tt++] = src;
dis[src] = 0;
inq[src] = 1;
while ( hh < tt ){
int now = q[hh++];
inq[now] = 0;
for (int i = head[now] ; i ; i = e[i].next){
if ( e[i].f && dis[e[i].to] > dis[now] + e[i].ct ){
dis[e[i].to] = dis[now] + e[i].ct;
prev[e[i].to] = i;
if ( !inq[e[i].to] ) q[tt++] = e[i].to , inq[e[i].to] = 1;
}
}
}
return dis[sink] < inf;
}
int dfs(){
int delta = inf , x = sink;
while ( x != src ){
delta = min(delta,e[prev[x]].f);
x = e[prev[x]].from;
}
x = sink;
while ( x != src ){
e[prev[x]].f -= delta;
e[prev[x] ^ 1].f += delta;
x = e[prev[x]].from;
}
return delta;
}
void init(){
for (int i = 1 ; i <= n ; i++) adde(i,sink,1,0);
for (int i = 1 ; i <= m ; i++)
for (int j = 1 ; j <= n ; j++){
adde(src,n + (i - 1) * n + j,1,0);
}
for (int i = 1 ; i <= n ; i++){
for (int j = 1 ; j <= m ; j++){
for (int k = 1 ; k <= n ; k++){
adde(n + (j - 1) * n + k,i,1,_time[j][i] * (n - k + 1));
}
}
}
}
int main(){
scanf("%d %d",&m,&n);
src = n * m + n + 1 , sink = src + 1;
for (int i = 1 ; i <= n ; i++){
for (int j = 1 ; j <= m ; j++){
scanf("%d",&_time[j][i]);
}
}
init();
while ( spfa() ){
mincost += dfs() * dis[sink];
}
ans = (double)mincost/(double)n;
printf("%.2lf\n",ans);
return 0;
}

浙公网安备 33010602011771号