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

    蒟蒻表示不太会。。。

    后来才想明白怎么做:一个拆了很多很多点的网络流模型。(想法其实是先考虑一个修理师的情况,再考虑多个的情况)

    把每个修理师拆成n个点,一辆车分别想着n个点连边,容量为1,费用为t * x  其中x = 1, 2, 3 ... n,表示在这之后修理车的人要总共等待t, t * 2, t * 3, t * 4...时间

    然后跑一边最小费用最大流就可以了。

    看上去非常对,就是这么做。。。搞定!

    (p.s. 作死小剧场:我建图的时候建错了,然后查spfa死活找不出错来>.<)

     1 /**************************************************************
     2     Problem: 1070
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:608 ms
     7     Memory:8744 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <cstring>
    12 #include <algorithm>
    13  
    14 using namespace std;
    15  
    16 const int inf = (int) 1e9;
    17 struct edges{
    18     int next, to, cost, f;
    19 } e[200000];
    20  
    21 int m, n, tot = 1, g[10000], first[10000], d[10000], q[200000];
    22 int a[1000][1000], s, t, ans;
    23 bool v[10000];
    24  
    25 inline void add_edge(int x, int y, int d, int c){
    26     e[++tot].next = first[x];
    27     first[x] = tot;
    28     e[tot].to = y;
    29     e[tot].f = d;
    30     e[tot].cost = c;
    31 }
    32  
    33 void add_Edges(int x, int y,int d, int c){
    34     add_edge(x, y, d, c);
    35     add_edge(y, x, 0, -c);
    36 }
    37  
    38 void build_graph(){
    39     for (int i = 1; i <= n; ++i)
    40         for (int j = 1; j <= m; ++j)
    41             for(int k = 1; k <= n; ++k)
    42                 add_Edges(i, j * n + k, 1, a[i][j] * k);
    43     s = m * n + n + 1,  t = m * n + n + 2;
    44     for (int i = 1; i <= n; ++i)
    45         add_Edges(s, i, 1, 0);
    46     for (int i = n + 1; i <= m * n + n; ++i)
    47         add_Edges(i, t, 1, 0);
    48 }
    49  
    50 inline int calc(){
    51     int flow = inf;
    52     for (int x = g[t]; x; x = g[e[x ^ 1].to])
    53         flow = min(flow, e[x].f);
    54     for (int x = g[t]; x; x = g[e[x ^ 1].to])
    55         e[x].f -= flow, e[x ^ 1].f += flow;
    56     return flow;
    57 }
    58  
    59 bool spfa(){
    60     for (int i = 1; i <= t; ++i)
    61         d[i] = inf;
    62     d[s] = 0, v[s] = 1;
    63     q[1] = s;
    64     int x, y;
    65     for(int l = 1, r = 1; l <= r; ++l){
    66         for (x = first[q[l]]; x; x = e[x].next){
    67             y = e[x].to;
    68             if (d[q[l]] + e[x].cost < d[y] && e[x].f){
    69                 d[y] = d[q[l]] + e[x].cost;
    70                 g[y] = x;
    71                 if (!v[y])
    72                     q[++r] = y, v[y] = 1;
    73             }
    74         }
    75         v[q[l]] = 0;
    76     }
    77     return d[t] != inf;
    78 }
    79  
    80 int main(){
    81     scanf("%d%d", &m, &n);
    82     for (int i = 1; i <= n; ++i)
    83         for (int j = 1; j <= m; ++j)
    84             scanf("%d", a[i] + j);
    85      
    86     build_graph();
    87     while (spfa())
    88         ans += calc() * d[t];
    89     printf("%.2lf
    ", (double) ans / n);
    90     return 0;
    91 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    数据库分区与分表
    Paxos算法简单介绍
    Zookeeper实现分布式锁服务(Chubby)
    java.lang.OutOfMemoryError: Java heap space错误及处理办
    关于分布式事务、两阶段提交协议、三阶提交协议
    Volatile
    寻找数组中只出现一次的数
    堆排序
    二叉树遍历 递归非递归
    redis 数据类型
  • 原文地址:https://www.cnblogs.com/rausen/p/4003568.html
Copyright © 2011-2022 走看看