• 修车[SCOI2007]


                         题目传送门

                1383. [SCOI 2007] 修车

    ★★★   输入文件:scoi2007_repair.in   输出文件:scoi2007_repair.out   简单对比
    时间限制:1 s   内存限制:256 MB

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

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

    输入

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

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

    输出

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

    样例

    repair.in

    2 2

    3 2

    1 4

    repair.out

    1.50

    数据范围:

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

      求平均时间最小等于求每个人等的总时间最小。

      如果一个人可以多线程工作的话这题就很好做了,然而如果一个人干完一个活才能干下一个,就要考虑前面的对后面的影响。对于一个工人来说,假设他修了n辆车,那么这n个车主等的总时间为w1*n+w2*(n-1)+...+wn*1(wi表示该工人修第i辆车的耗时),也就是说倒数第i辆车对总时间的贡献为w*i。所以我们把每个工人分出n个时段,每个第i个时段的耗时为i*w。最后跑一边最小费用最大流即可。

      具体建模方式:n辆车与n*m个工人时段分属两个不同集合。第i辆车与第j个工人的第k个时段之间连容量为1,费用为k*wi,j的边。s向每辆车连容量为1,费用为0的边。每个工人时段向t连容量为1,费用为0的边。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<bitset>
     7 #define LL long long
     8 #define RI register int
     9 using namespace std;
    10 const int INF = 0x7ffffff ;
    11 const int N = 60 + 2 ;
    12 const int M = 9 + 2 ;
    13 const int NN = 600 + 10 ;
    14 const int FN = 1000 + 10 ;
    15 const int MM = 1e6 + 10 ;
    16 
    17 inline int read() {
    18     int k = 0 , f = 1 ; char c = getchar() ;
    19     for( ; !isdigit(c) ; c = getchar())
    20       if(c == '-') f = -1 ;
    21     for( ; isdigit(c) ; c = getchar())
    22       k = k*10 + c-'0' ;
    23     return k*f ;
    24 }
    25 struct Edge {
    26     int to, next, flow, cost ;
    27 }e[MM] ;
    28 int n, m, s, t, ansf, ansc ; int head[FN], dis[FN] ; bool vis[FN] ;
    29 inline void add_edge(int x,int y,int ff,int cc) {
    30     static int cnt = 1 ;
    31     e[++cnt].to = y, e[cnt].next = head[x], head[x] = cnt, e[cnt].flow = ff, e[cnt].cost = cc ;
    32     e[++cnt].to = x, e[cnt].next = head[y], head[y] = cnt, e[cnt].flow = 0, e[cnt].cost = -cc ;
    33 }
    34 
    35 inline bool spfa() {
    36     for(int i=1;i<=t;i++) dis[i] = INF ; dis[s] = 0 ;
    37     deque<int>q ; q.push_back(s) ; bitset<FN>inq ; inq[s] = 1 ;
    38     while(!q.empty()) {
    39         int x = q.front() ; q.pop_front() ; inq[x] = 0 ;
    40         for(int i=head[x];i;i=e[i].next) {
    41             int y = e[i].to ; if(!e[i].flow) continue ;
    42             if(dis[y] > dis[x]+e[i].cost) {
    43                 dis[y] = dis[x]+e[i].cost ;
    44                 if(!inq[y]) {
    45                     inq[y] = 1 ;
    46                     if(!q.empty() && dis[y] < dis[q.front()]) q.push_front(y) ;
    47                     else q.push_back(y) ;
    48                 }
    49             }
    50         }
    51     }
    52     return dis[t] < INF ;
    53 }
    54 int FFdfs(int x,int minflow) {
    55     vis[x] = 1 ;
    56     if(x == t || !minflow) return minflow ;
    57     int fflow = 0 ;
    58     for(int i=head[x];i;i=e[i].next) {
    59         int y = e[i].to ; if(!e[i].flow || vis[y] || dis[y] != dis[x]+e[i].cost) continue ;
    60         int temp = FFdfs(y,min(minflow,e[i].flow)) ;
    61         fflow += temp, minflow -= temp ;
    62         e[i].flow -= temp, e[i^1].flow += temp ;
    63         ansc += temp*e[i].cost ;
    64         if(!minflow) break ;
    65     }
    66     return fflow ;
    67 }
    68 
    69 int main() {
    70     freopen("scoi2007_repair.in","r",stdin) ;
    71     freopen("scoi2007_repair.out","w",stdout) ;
    72     m = read(), n = read() ; s = n+NN+1, t = s+1 ;
    73     for(int i=1;i<=n;i++) {
    74         add_edge(s,i+NN,1,0) ;
    75         for(int j=1;j<=m;j++) {
    76             int x = read() ;
    77             for(int k=1;k<=n;k++) {
    78                 add_edge(i+NN,(j-1)*n+k,1,k*x) ;
    79             }
    80         }
    81     }
    82     for(int i=1;i<=n*m;i++) add_edge(i,t,1,0) ;
    83     while(spfa()) {
    84         vis[t] = 1 ;
    85         while(vis[t]) {
    86             memset(vis,0,sizeof(vis)) ;
    87             ansf += FFdfs(s,INF) ;
    88         }
    89     }
    90     double ans = (double)ansc/(double)n ;
    91     printf("%.2lf",ans) ;
    92     return 0 ;
    93 }
  • 相关阅读:
    拦截器
    Mysql修改字段类型,修改字段名
    1.Spring对JDBC整合支持
    由system.currentTimeMillis() 获得当前的时间
    spring 对jdbc的简化
    spring对JDBC的整合支持
    java 运行时异常与非运行时异常理解
    MySQL5.7 的新特点
    基于 SSL 的 Nginx 反向代理
    如何使用 lsyncd 实时同步并执行 shell 命令
  • 原文地址:https://www.cnblogs.com/zub23333/p/8849048.html
Copyright © 2020-2023  润新知