[BZOJ1070][SCOI2007]修车

1070: [SCOI2007]修车

Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 6007  Solved: 2559 [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)

 

对于每个维修师傅拆成$n$个点,每个点在连边时费用对应乘上相应的倍数,因为如果一个维修师傅修多个车的话等待时间需要乘上一定倍数。然后跑最小费用最大流

 

#include <cstdio>
inline int readint(){
    int f = 1, n = 0;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch <= '9' && ch >= '0'){
        n = (n << 1) + (n << 3) + ch - '0';
        ch = getchar(); 
    }
    return f * n;
}
const int maxn = 100, maxm = 15, INF = 0x3f3f3f3f;
struct Edge{
    int to, cap, cost, next;
    Edge(){}
    Edge(int _t, int _w, int _c, int _n): to(_t), cap(_w), cost(_c), next(_n){}
}e[maxn + maxn * maxn * maxm + maxn * maxm << 1];
int fir[maxn + maxn * maxm] = {0}, cnt = 1;
inline void ins(int u, int v, int w, int c){
    e[++cnt] = Edge(v, w, c, fir[u]); fir[u] = cnt;
    e[++cnt] = Edge(u, 0, -c, fir[v]); fir[v] = cnt;
}
int sour, sink;
bool inq[maxn + maxn * maxm] = {false};
int dis[maxn + maxn * maxm];
int q[maxn + maxn * maxm], head, tail;
int pre[maxn + maxn * maxm];
bool SPFA(){
    for(int i = sour; i <= sink; i++){
        dis[i] = INF;
        inq[i] = false;
        pre[i] = 0;
    }
    head = tail = 0;
    dis[sour] = 0;
    inq[sour] = true;
    q[tail++] = sour;
    int u, v;
    while(head != tail){
        u = q[head++];
        if(head == 1600) head = 0;
        inq[u] = false;
        for(int i = fir[u]; i; i = e[i].next){
            v = e[i].to;
            if(e[i].cap && dis[v] > dis[u] + e[i].cost){
                dis[v] = dis[u] + e[i].cost;
                pre[v] = i;
                if(!inq[v]){
                    inq[v] = true;
                    q[tail++] = v;
                    if(tail == 1600) tail = 0;
                }
            }
        }
    }
    return dis[sink] != INF;
}
int MCMF(){
    int flow, cost = 0;
    while(SPFA()){
        flow = INF;
        for(int i = pre[sink]; i; i = pre[e[i ^ 1].to])
            if(e[i].cap < flow) flow = e[i].cap;
        for(int i = pre[sink]; i; i = pre[e[i ^ 1].to]){
            e[i].cap -= flow;
            e[i ^ 1].cap += flow;
        }
        cost += flow * dis[sink];
    }
    return cost;
}
int main(){
    int m, n;
    m = readint();
    n = readint();
    sour = 0;
    sink = n + n * m + 1;
    for(int i = 1; i <= n; i++) ins(sour, i, 1, 0);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++){
            int t = readint();
            for(int k = 1; k <= n; k++)
                ins(i, j * n + k, 1, k * t);
        }
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= n; j++)
            ins(i * n + j, sink, 1, 0);
    printf("%.2lf\n", MCMF() * 1.0 / n);
    return 0;
}

 

 

 

posted @ 2017-08-27 16:08  jzyy  阅读(144)  评论(0编辑  收藏  举报