首页 > 代码库 > [SCOI2007]修车

[SCOI2007]修车

[SCOI2007]修车

https://www.luogu.org/problem/show?pid=2053

题目描述

同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。

说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。

输入输出格式

输入格式:

 

第一行有两个数M,N,表示技术人员数与顾客数。

接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T。

 

输出格式:

 

最小平均等待时间,答案精确到小数点后2位。

 

输入输出样例

输入样例#1:
2 23 21 4
输出样例#1:
1.50

说明

(2<=M<=9,1<=N<=60), (1<=T<=1000)

技术分享

#include<bits/stdc++.h>#define N 1000001using namespace std;int front[N],cap[N],a[N],nextt[N],to[N],from[N],fa[N],dis[N],cost[N];int n,m,k,ans,tot=1,flow,src,decc,ti[1001][1001];bool inque[N];queue<int>q;void add(int u,int v,int w,int val){    to[++tot]=v;nextt[tot]=front[u];front[u]=tot;cap[tot]=w;cost[tot]=val;from[tot]=u;    to[++tot]=u;nextt[tot]=front[v];front[v]=tot;cap[tot]=0;cost[tot]=-val;from[tot]=v;}bool spfa(){    memset(inque,0,sizeof(inque));    for(int i=0;i<=n*m+n+m+1;i++) dis[i]=2e9;    q.push(src);    inque[src]=1;    dis[src]=0;    int now;    while(!q.empty())    {        now=q.front();        q.pop();        inque[now]=0;        for(int i=front[now];i;i=nextt[i])        {            int t=to[i];            if(dis[t]>dis[now]+cost[i]&&cap[i]>0)            {                dis[t]=dis[now]+cost[i];                fa[t]=i;                if(!inque[t])                {                    inque[t]=1;                    q.push(t);                }            }        }    }    if(dis[decc]==2e9) return false;    now=decc;    while(now!=src)    {        cap[fa[now]]--;        cap[fa[now]^1]++;        ans+=cost[fa[now]];        now=from[fa[now]];    }    return true;}int main(){    scanf("%d%d",&m,&n);    decc=n*m+n+m+1;    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            scanf("%d",&ti[j][i]);    for(int i=1;i<=m;i++) add(src,i,9999999,0);    for(int i=1;i<=m;i++)    {        for(int j=1;j<=n;j++)        {            add(i,m+n+(i-1)*n+j,1,0);            for(int k=1;k<=n;k++)            {                add(m+n+(i-1)*n+j,m+k,1,j*ti[i][k]);            }        }    }    for(int i=1;i<=n;i++)    {        add(m+i,decc,1,0);    }    while(spfa());    double anss=ans/(n*1.0);    printf("%.2lf",anss);}

 

[SCOI2007]修车