P1251 餐巾计划问题 网络流

P1251 餐巾计划问题

 

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 5005, inf = 0x3f3f3f3f;
 5 struct Edge {
 6     int from, to;
 7     ll cap, flow, cost;
 8 };
 9 
10 struct MCMF {
11     int n, m, s, t;
12     vector<Edge> edges;
13     vector<int> G[maxn];
14     int inq[maxn];
15     ll d[maxn];
16     int p[maxn];
17     ll a[maxn];
18 
19     void init(int n) {
20         this->n = n;
21         for (int i = 1; i <= n; ++i) G[i].clear();
22         edges.clear();
23     }
24 
25     void AddEdge(int from, int to, ll cap, ll cost) {
26         edges.push_back((Edge){from, to, cap, 0, cost});
27         edges.push_back((Edge){to, from, 0, 0, -cost});
28         m = edges.size();
29         G[from].push_back(m-2);
30         G[to].push_back(m-1);
31     }
32     bool BellmanFord(int s, int t, ll& flow, ll& cost) {
33         for (int i = 1; i <= n; ++i) d[i] = inf;
34         memset(inq, 0, sizeof(inq));
35         d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = inf;
36 
37         queue<int> que;
38         que.push(s);
39         while (!que.empty()) {
40             int u = que.front(); que.pop();
41             inq[u] = 0;
42             for (int i = 0; i < G[u].size(); ++i) {
43                 Edge& e = edges[G[u][i]];
44                 if (e.cap > e.flow && d[e.to] > d[u] + e.cost) {
45                     d[e.to] = d[u] + e.cost;
46                     p[e.to] = G[u][i];
47                     a[e.to] = min(a[u], e.cap-e.flow);
48                     if (!inq[e.to]) { que.push(e.to); inq[e.to] = 1; }
49                 }
50             }
51         }
52         if (d[t] == inf) return false;
53         flow += a[t];
54         cost += d[t] * a[t];
55         int u = t;
56         while (u != s) {
57             edges[p[u]].flow += a[t];
58             edges[p[u]^1].flow -= a[t];
59             u = edges[p[u]].from;
60         }
61         return true;
62     }
63     ll mincost(int s, int t) {
64         ll flow = 0, cost = 0;
65         while (BellmanFord(s, t, flow, cost));
66         return cost;
67     }
68 }mcmf;
69 int r[maxn];
70 int main() {
71     int N; scanf("%d",&N);
72     for (int i = 1; i <= N; ++i) {
73         scanf("%d",&r[i]);
74     }
75     int p, m, f, n, s;
76     scanf("%d%d%d%d%d",&p,&m,&f,&n,&s);
77 
78     /// i为干净餐巾量,i+N为脏餐巾量
79     int be = 2*N+1, ed = 2*N+2;
80     mcmf.init(2*N+2);
81     for (int i = 1; i <= N; ++i) {
82         /// 通过购买来获得干净餐巾
83         mcmf.AddEdge(be,i,r[i],p);
84         /// 当天的脏餐巾如何使用
85         mcmf.AddEdge(be,i+N,r[i],0);
86         /// 当天的脏餐巾留到明天
87         if (i+1 <= N) mcmf.AddEdge(i+N,(i+1)+N,inf,0);
88         /// 通过快洗部洗脏餐巾
89         if (i+m <= N) mcmf.AddEdge(i+N,i+m,inf,f);
90         /// 通过慢洗部洗脏餐巾
91         if (i+n <= N) mcmf.AddEdge(i+N,i+n,inf,s);
92         /// 使用当天的干净餐巾
93         mcmf.AddEdge(i,ed,r[i],0);
94     }
95     ll ans = mcmf.mincost(be,ed);
96     printf("%lld\n",ans);
97     return 0;
98 }

 

posted @ 2019-11-05 19:05  麻辣猪仔  阅读(103)  评论(0编辑  收藏  举报