首页 > 代码库 > BZOJ1070 [SCOI2007]修车

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\n", (double) ans / n);90     return 0;91 }
View Code

 

BZOJ1070 [SCOI2007]修车