1070: [SCOI2007]修车

1070: [SCOI2007]修车

https://www.lydsy.com/JudgeOnline/problem.php?id=1070

分析:

  每个第几次修车等的时间都不一样,当前第i个人修理的车的队列是a1,a2...ak,那么对于ak等待的时间就是前面所有车的修理时间之和。如果这样建图显然空间开不下。考虑换种建图方式,a1对于后面所有车的等待时间都会加上它的修理时间,每个修理的汽车,都会对后面所有修的车加上它的修理时间。

  所以每个人拆成n个点,第i个点表示倒数第i个修的车,那么所有的花费都应乘以i。

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<cctype>
 7 #include<set>
 8 #include<vector>
 9 #include<queue>
10 #include<map>
11 #define fi(s) freopen(s,"r",stdin);
12 #define fo(s) freopen(s,"w",stdout);
13 using namespace std;
14 typedef long long LL;
15 
16 inline int read() {
17     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
18     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
19 }
20 
21 const int INF = 1e9;
22 const int N = 1005;
23 
24 struct Edge{
25     int u, to, nxt, f, c;
26     Edge () {} 
27     Edge (int _1,int _2,int _3,int _4,int _5) { u = _1, to = _2, f = _3, c = _4, nxt = _5; }
28 }e[100005];
29 int head[N], En = 1, S, T;
30 
31 namespace MaxflowMincost{
32     int pre[N], dis[N], q[100005], Maxflow, Mincost; // q[N]!!! 
33     bool vis[N];
34     bool spfa() {
35         for (int i=1; i<=T; ++i) dis[i] = INF, vis[i] = false, pre[i] = 0;
36         int L = 1, R = 0;
37         q[++R] = S, dis[S] = 0, vis[S] = true, pre[S] = 0;
38         while (L <= R) {
39             int u = q[L ++]; vis[u] = false;
40             for (int i=head[u]; i; i=e[i].nxt) {
41                 int v = e[i].to;
42                 if (dis[v] > dis[u] + e[i].c && e[i].f > 0) {
43                     dis[v] = dis[u] + e[i].c;
44                     pre[v] = i;
45                     if (!vis[v]) q[++R] = v, vis[v] = true;
46                 }
47             }
48         }
49         return dis[T] != INF;
50     }
51     void mcf() {
52         int zf = INF;
53         for (int i=T; i!=S; i=e[pre[i]].u) 
54             zf = min(zf, e[pre[i]].f);
55         for (int i=T; i!=S; i=e[pre[i]].u) 
56             e[pre[i]].f -= zf, e[pre[i] ^ 1].f += zf;
57         Maxflow += zf, Mincost += dis[T] * zf;
58     }
59     void solve() {
60         Mincost = Maxflow = 0;
61         while (spfa()) 
62             mcf();
63     }
64 }
65 
66 void add_edge(int u,int v,int f,int c) {
67     ++En; e[En] = Edge(u, v, f, c, head[u]); head[u] = En;
68     ++En; e[En] = Edge(v, u, 0, -c, head[v]); head[v] = En;
69 }
70 
71 int main() {
72     int m = read(), n = read();
73     S = n + m * n + 1, T = S + 1;
74     
75     for (int i=1; i<=n; ++i) add_edge(S, i, 1, 0);
76     for (int i=1; i<=n; ++i) { // 第i辆车 
77         for (int j=1; j<=m; ++j) { // 第j个人 
78             int w = read();
79             for (int k=1; k<=n; ++k) // 第k次修 
80                 add_edge(i, j * n + k, 1, k * w); // i+n, j*n+k !!!
81         }
82     }
83     for (int i=n+1,lim=(n+m*n); i<=lim; ++i) add_edge(i, T, 1, 0);
84     
85     MaxflowMincost::solve();
86     int ans = MaxflowMincost::Mincost;
87     printf("%.2lf", (1.0 * ans) / (1.0 * n));
88     return 0;
89 }
原文地址:https://www.cnblogs.com/mjtcn/p/9724597.html