蒟蒻表示不太会。。。
后来才想明白怎么做:一个拆了很多很多点的网络流模型。(想法其实是先考虑一个修理师的情况,再考虑多个的情况)
把每个修理师拆成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 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen