• BZOJ1070 [SCOI2007]修车


    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个点,表示这是他修的倒数第几辆,那么当前的车只会影响后面的车的等待时间,假如现在是倒数第j辆车,那么花费就是j*f【i】【k】,f【i】【k】表示第i个维修工人修序号为k的车的花费。然后n辆车连上n*m个点,容量为1,车再向源点点连容量为1的边,n*m个点向汇点连容量为1的边,跑spfa。

     1 #include <iostream>
     2 #include <iomanip>
     3 #include <cstdlib>
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <cstring>
     7 #include <string>
     8 #include <algorithm>
     9 #define MIN(a,b) a<b?a:b
    10 #define RG register
    11 const int N = 5000;
    12 const int M = 1000000;
    13 const int inf = 2147483641;
    14 
    15 using namespace std;
    16 
    17 int gi(){
    18     char ch=getchar();int x=0;
    19     while(ch<'0' || ch>'9') ch=getchar();
    20     while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    21     return x;
    22 }
    23 
    24 int n,m,q,ans,cnt=1,S,T;
    25 int fa[N],f[N][N],nxt[M],c[N][N],head[N],s[M],dis[M],vis[M];
    26 
    27 struct date{
    28     int from,to,val,s;
    29 }nn[M];
    30 
    31 void link(int l,int r,int val,int s){
    32     nn[++cnt]=(date){l,r,val,s},nxt[cnt]=head[l],head[l]=cnt;
    33     nn[++cnt]=(date){r,l,0,-s},nxt[cnt]=head[r],head[r]=cnt;
    34     return;
    35 }
    36 
    37 int spfa(){
    38     int l=0,r=1;
    39     for (RG int i=S; i<=T; ++i) dis[i]=inf;
    40     s[1]=0,dis[0]=0,vis[0]=1;
    41     while(l<r){
    42         ++l;
    43         for (RG int i=head[s[l]]; i; i=nxt[i])
    44             if (nn[i].val && dis[nn[i].to]>dis[s[l]]+nn[i].s){
    45                 fa[nn[i].to]=i;
    46                 dis[nn[i].to]=dis[s[l]]+nn[i].s;
    47                 if (!vis[nn[i].to]){
    48                     vis[nn[i].to]=1;s[++r]=nn[i].to;
    49                 }
    50             }
    51         vis[s[l]]=0;
    52     }
    53     if (dis[T]==inf) return 0;
    54     int tmp=inf;
    55     for (RG int i=fa[T]; i; i=fa[nn[i].from]) tmp=MIN(tmp,nn[i].val);
    56     for (RG int i=fa[T]; i; i=fa[nn[i].from]) nn[i].val-=tmp,nn[i^1].val+=tmp;
    57     ans+=tmp*dis[T];
    58     return 1;
    59 }
    60 
    61 int main(){
    62     m=gi(),n=gi();
    63     for (RG int i=1; i<=n; ++i) link(S,i,1,0);
    64     for (RG int i=1; i<=n; ++i)
    65         for (RG int j=1; j<=m; ++j)
    66             f[j][i]=gi();
    67     ans=n,q=n;
    68     for (RG int i=1; i<=m; ++i)
    69         for (RG int j=1; j<=q; ++j)
    70             c[i][j]=++ans;
    71     T=ans+1;
    72     ans=0;
    73     for (RG int i=1; i<=n; ++i)
    74         for (RG int j=1; j<=m; ++j)
    75             for (RG int k=1; k<=q; ++k)
    76                 link(i,c[j][k],1,f[j][i]*k);
    77     for (RG int j=1; j<=m; ++j)
    78         for (RG int k=1; k<=q; ++k)
    79             link(c[j][k],T,1,0);
    80     ans=0;
    81     while(spfa());
    82     printf("%.2lf",(ans*1.0)/n);
    83     return 0;
    84 }
  • 相关阅读:
    2020北航OO第二单元总结
    2020北航OO第一单元总结
    OO结课了,狂喜
    BUAAOO第三单元总结
    BUAAOO第二单元代码分析
    BUAAOO第一单元代码分析
    OO第四次博客作业
    OO第三次博客作业
    OO第二次博客作业
    OO第一次博客作业
  • 原文地址:https://www.cnblogs.com/cjk2001/p/6442016.html
Copyright © 2020-2023  润新知