zoukankan      html  css  js  c++  java
  • bzoj 1070[SCOI2007]修车

    1070: [SCOI2007]修车

    Time Limit: 1 Sec  Memory Limit: 128 MB

    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)

    对维修工拆点, 第k个维修工表示这辆车是他修的倒数k辆

    对于 第 j 辆车连向第i个维修工的第k个节点的权值就是 k * a[i][j], 因为在他之后修的车都会加上等待的时间。

    根据网络流的性质,他会优先跑小的边

    所以跑费用流就是总的等待时间

      1 #include <iostream> 
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <queue>
      6 #define LL long long 
      7 
      8 using namespace std;
      9 
     10 queue<int> q;
     11 int cnt = 0;
     12 const int MAXN = 1e3;
     13 int ti;
     14 int dis[MAXN];
     15 int flag[MAXN];
     16 int head[MAXN];
     17 int N, M;
     18 int V;
     19 int S, T;
     20 int pre[MAXN];
     21 int e[MAXN];
     22 struct edge {
     23     int v;
     24     int next;
     25     int w;
     26     int cost;
     27 } g[600 * 600 * 10];
     28 
     29 double ans = 0;
     30 void addedge(int u, int v, int w, double cost)
     31 {
     32     g[cnt].v = v;
     33     g[cnt].w = w;
     34     g[cnt].cost = cost;
     35     g[cnt].next = head[u];
     36     head[u] = cnt++;
     37 }
     38 inline LL read()
     39 {
     40     LL x = 0, w = 1; char ch = 0;
     41     while(ch < '0' || ch > '9') {
     42         if(ch == '-') {
     43             w = -1;
     44         }
     45         ch = getchar();
     46     }
     47     while(ch >= '0' && ch <= '9') {
     48         x = x * 10 + ch - '0';
     49         ch = getchar();
     50     }
     51     return x * w;
     52 }
     53 
     54 bool SPFA()
     55 {
     56     while(!q.empty()) {
     57         q.pop();
     58     }
     59     memset(pre, 0, sizeof pre);
     60     memset(flag, 0, sizeof flag);
     61     memset(dis, 0x3f, sizeof dis);
     62     dis[0] = 0;
     63     q.push(S);
     64     while(!q.empty()) {
     65         int t = q.front();
     66         flag[t] = 0;
     67         q.pop();
     68         for(int j = head[t]; j != -1; j = g[j].next) {
     69             int to = g[j].v;
     70             if(dis[to] > dis[t] + g[j].cost && g[j].w > 0) {
     71                 dis[to] = dis[t] + g[j].cost;
     72             //    cout<<dis[to]<<endl;
     73                 pre[to] = t;
     74                 /*if(dis[to] < 0 && to == 0) {
     75                     for(int j = t; j ; j = pre[j]) {
     76                         cout<<j<<" "<<dis[j]<<endl;
     77                     }
     78                     cout<<endl;
     79                     exit(0);
     80                 }*/
     81                 e[to] = j;
     82                 if(!flag[to]) {
     83                     flag[to] = 1;
     84                     q.push(to);
     85                 }
     86             }
     87         }
     88     }
     89     if(!pre[T]) {
     90         return false;
     91     }
     92     ans += dis[T];
     93     int minflow = 1e9;
     94     for(int j = T; j; j = pre[j]) {
     95         //cout<<j<<" ";
     96         minflow = min(minflow, g[e[j]].w);
     97     }
     98     //cout<<endl;
     99     //cout<<dis[T]<<" "<<minflow<<endl<<endl;
    100     for(int j = T; j; j = pre[j]) {
    101         g[e[j]].w -= minflow;
    102         g[e[j] ^ 1].w += minflow;
    103     }
    104     return true;
    105 }
    106 
    107 int main()
    108 {
    109     memset(head, -1, sizeof head);
    110     M = read(), N = read();
    111     V = M * N;
    112     S = 0, T = V + N + 1;
    113     for(int i = 1; i <= N; i++) {
    114         addedge(S, V + i, 1, 0);
    115         addedge(V + i,S, 0, 0);
    116         for(int j = 1; j <= M; j++) {
    117             scanf("%d", &ti);
    118             for(int t = 1; t <= N; t++) {
    119                 addedge((t - 1) * M + j, V + i, 0, -1 * ti * t);
    120                 addedge(V + i, (t - 1) * M + j, 1, 1 * ti * t);
    121             }
    122         }
    123     }
    124     for(int i = 1; i <= M * N; i++) {
    125         addedge(i, T, 1, 0);
    126         addedge(T, i, 0, 0);
    127     }
    128     while(SPFA()) {
    129     }
    130     printf("%.2lf
    ", ans / N);
    131     return 0;
    132 }
    133 
    134 /*
    135 2 2
    136 3 2
    137 1 4
    138 
    139 */
    View Code
  • 相关阅读:
    HackerRank "Arithmetic Expressions" !
    HackerRank "Poker Nim"
    HackerRank "Nimble Game"
    HackerRank "Misère Nim"
    HackerRank "Triangle Numbers"
    HackerRank "Flipping the Matrix"
    HackerRank "Chessboard Game, Again!"
    HackerRank "Tower Breakers, Again!"
    HackerRank
    HackerRank "Richie Rich"
  • 原文地址:https://www.cnblogs.com/wuenze/p/8638955.html
Copyright © 2011-2022 走看看