bzoj1070: [SCOI2007]修車

題目鏈接

bzoj1070

題目描述

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)

題解

這題每個顧客的等待時間也要計算,這便是麻煩之處。
考慮第i個人修第j輛車,如果這輛車是倒數第k臺被修理的,那麼k輛車都有等待t的時間,相當於費用爲t[j,i]* k。那麼我們把m個人拆成n*m個點,每個人的第i個點代表他修理的車是倒數第i輛,將這個點分別向n輛車連邊,費用爲i *t。跑一遍費用流就行了。其實就相當於將所有情況的費用提前計算出來。


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;

#define N 605
struct edge{
    int x,next,cost,data,f;
}e[100000];
int first[N],c[N*N],v[N],dis[N],ti[N][N],pre[N],tot=1,n,m,p,q,s,t;

void add(int x,int y,int d,int c){
    e[++tot].x=y;
    e[tot].data=d;
    e[tot].cost=c;
    e[tot].f=x;
    e[tot].next=first[x];
    first[x]=tot;
    if(~tot&1) add(y,x,0,-c); 
} 
bool spfa(){
    memset(dis,63,sizeof(dis));
    memset(v,0,sizeof(v));
    v[c[1]=s]=1; dis[s]=0;
    for(p=q=1;p<=q;v[c[p]]=0,p++)
     for(int i=first[c[p]];i;i=e[i].next)
     if(e[i].data&&dis[e[i].x]>dis[c[p]]+e[i].cost){
        dis[e[i].x]=dis[c[p]]+e[i].cost;
        pre[e[i].x]=i;
        if(!v[e[i].x]) v[c[++q]=e[i].x]=1;
     }
    return dis[t]!=dis[0];
}
int cost_flow(){
    int ans=0,flow;
    while(spfa()){
        flow=1000000007;
        for(int i=pre[t];i;i=pre[e[i].f]) flow=min(flow,e[i].data);
        ans+=flow*dis[t];
        for(int i=pre[t];i;i=pre[e[i].f]) e[i].data-=flow,e[i^1].data+=flow;
    }
    return ans;
}
int main(){
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++) scanf("%d",&ti[i][j]);
    s=n*m+n+1; t=n*m+n+2;
    for(int i=1;i<=n*m;i++) add(s,i,1,0);
    for(int i=1;i<=n;i++) add(i+n*m,t,1,0);
    for(int i=1;i<=m;i++)
     for(int j=1;j<=n;j++)
      for(int k=1;k<=n;k++) add((i-1)*n+k,n*m+j,1,ti[j][i]*k);
    printf("%.2f",(double)cost_flow()/n);
    return 0;
}
發佈了60 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章