zoukankan      html  css  js  c++  java
  • 洛谷P2053 修车

    修车修到jiry报废(滑稽)

    题意:m个人修n个车,同时开始。

    每辆车只能给一个人修。每个人修每辆车的用时都不同。

    问怎样安排能使每辆车的等待时间总和最少。

    解:

    一直想的是用以流量表示一个人,没想到是一流量表示一辆车......

    答案统计也想错了...应该是统计每辆车修的时候对它以及它后面车的贡献。

    比如当前这辆车的后面还有k辆,那么时间就要乘k + 1

    每辆车可以给每个人修,后面可以安排任意辆车。据此拆点,把每个人拆成n个。

    源点向车连边,车向每个人的后面有几辆车(一共m * n个点)连边,然后连到汇点。

    跑最小费用最大流即可。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <queue>
      4 #include <cstring>
      5 
      6 const int N = 710, M = 1000010, INF = 0x3f3f3f3f;
      7 
      8 struct Edge {
      9     int nex, v, c, len;
     10 }edge[M << 1]; int top = 1;
     11 
     12 int e[N], d[N], vis[N], pre[N], flow[N];
     13 std::queue<int> Q;
     14 int G[70][13];
     15 
     16 inline void add(int x, int y, int z, int w) {
     17     top++;
     18     edge[top].v = y;
     19     edge[top].c = z;
     20     edge[top].len = w;
     21     edge[top].nex = e[x];
     22     e[x] = top;
     23 
     24     top++;
     25     edge[top].v = x;
     26     edge[top].c = 0;
     27     edge[top].len = -w;
     28     edge[top].nex = e[y];
     29     e[y] = top;
     30     return;
     31 }
     32 
     33 inline bool SPFA(int s, int t) {
     34     memset(d, 0x3f, sizeof(d));
     35     d[s] = 0;
     36     flow[s] = INF;
     37     vis[s] = 1;
     38     Q.push(s);
     39     while(!Q.empty()) {
     40         int x = Q.front();
     41         Q.pop();
     42         vis[x] = 0;
     43         for(int i = e[x]; i; i = edge[i].nex) {
     44             int y = edge[i].v;
     45             if(edge[i].c && d[y] > d[x] + edge[i].len) {
     46                 d[y] = d[x] + edge[i].len;
     47                 pre[y] = i;
     48                 flow[y] = std::min(flow[x], edge[i].c);
     49                 if(!vis[y]) {
     50                     vis[y] = 1;
     51                     Q.push(y);
     52                 }
     53             }
     54         }
     55     }
     56     return d[t] < INF;
     57 }
     58 
     59 inline void update(int s, int t) {
     60     int temp = flow[t];
     61     while(t != s) {
     62         int i = pre[t];
     63         edge[i].c -= temp;
     64         edge[i ^ 1].c += temp;
     65         t = edge[i ^ 1].v;
     66     }
     67     return;
     68 }
     69 
     70 inline int solve(int s, int t, int &cost) {
     71     int ans = 0;
     72     cost = 0;
     73     while(SPFA(s, t)) {
     74         ans += flow[t];
     75         cost += flow[t] * d[t];
     76         update(s, t);
     77     }
     78     return ans;
     79 }
     80 
     81 int m;
     82 inline int id(int x, int y) {
     83     return (x - 1) * m + y;
     84 }
     85 
     86 int main() {
     87 
     88     int n;
     89     scanf("%d%d", &m, &n);
     90     for(int i = 1; i <= n; i++) {
     91         for(int j = 1; j <= m; j++) {
     92             scanf("%d", &G[i][j]);
     93         }
     94     }
     95     int s = (m + 1) * n + 1;
     96     int t = s + 1;
     97     for(int a = 1; a <= n; a++) {
     98         add(s, a, 1, 0);
     99         for(int j = 1; j <= m; j++) {
    100             for(int i = 1; i <= n; i++) {
    101                 add(a, n + id(i, j), 1, i * G[a][j]);
    102             }
    103         }
    104         for(int j = 1; j <= m; j++) {
    105             add(n + id(a, j), t, 1, 0);
    106         }
    107     }
    108     int ans;
    109     solve(s, t, ans);
    110     printf("%.2f", 1.0 * ans / n);
    111     return 0;
    112 }
    AC代码
  • 相关阅读:
    我了解到的新知识之----如何使用Python获取最新外汇汇率信息
    软工实践个人总结
    第06组 Beta版本演示
    第06组 Beta冲刺(5/5)
    第06组 Beta冲刺(4/5)
    第06组 Beta冲刺(3/5)
    第06组 Beta冲刺(2/5)
    第06组 Beta冲刺(1/5)
    第06组 Alpha事后诸葛亮
    第06组 Alpha冲刺(6/6)
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10110978.html
Copyright © 2011-2022 走看看