SDOI 2010 星际竞速 | 费用流

Posted milky-w

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDOI 2010 星际竞速 | 费用流相关的知识,希望对你有一定的参考价值。

luogu 2469

S -> i (cost=Ai,cap=1)         S -> i‘(cost=0, cap=1)
i‘-> j (cost=wi,cap=1)(i < j)  i -> T (cost=0, cap=1)

i -> i‘(×)

 1 #include <cstdio>
 2 #include <string>
 3 #include <vector>
 4 #include <queue>
 5 #include <cstring>
 6 
 7 typedef long long ll;
 8 const int N = 2000;
 9 const ll INF = 1e18;
10 
11 int read() {
12     int x = 0, f = 1;
13     char c = getchar();
14     while (!isdigit(c)) {
15         if (c == -) f = -1;
16         c = getchar();
17     }
18     while (isdigit(c)) {
19         x = (x << 3) + (x << 1) + (c ^ 48);
20         c = getchar();
21     }
22     return x * f;
23 }
24 
25 ll min(ll x, ll y) {
26     if (x <= y) return x; return y;
27 }
28 
29 int n, m, S, T, A[N];
30 
31 struct Edge {
32     int from, to; ll flow, cap, cost;
33 };
34 std::vector<Edge> edges;
35 std::vector<int> G[N];
36 
37 int p[N], inq[N]; ll a[N], d[N];
38 
39 bool SPFA(ll &flow, ll &cost) {
40     memset(inq, 0, sizeof inq);
41     for (int i = 0; i < n; ++ i) d[i] = INF;
42     d[S] = p[S] = 0, inq[S] = 1, a[S] = INF;
43     std::queue<int> Q; Q.push(S);
44     while (!Q.empty()) {
45         int u = Q.front(); Q.pop(); inq[u] = 0;
46         int size = G[u].size();
47         for (int i = 0; i < size; ++ i) {
48             Edge &e = edges[G[u][i]];
49             if (e.cap > e.flow && d[e.to] > d[u] + e.cost) {
50                 d[e.to] = d[u] + e.cost;
51                 p[e.to] = G[u][i];
52                 a[e.to] = min(a[u], e.cap - e.flow);
53                 if (!inq[e.to]) Q.push(e.to), inq[e.to] = 1;
54             }
55         }
56     }
57     if (d[T] == INF) return false;
58     flow += a[T], cost += a[T] * d[T];
59     int u = T;
60     while (u != S) {
61         edges[p[u]].flow += a[T];
62         edges[p[u]^1].flow -= a[T];
63         u = edges[p[u]].from;
64     }
65     return true;
66 }
67 
68 ll minCost() {
69     ll flow = 0, cost = 0;
70     while (SPFA(flow, cost)) {}
71     return cost;
72 }
73 
74 void addEdge(int from, int to, ll cap, ll cost) {
75     edges.push_back((Edge){from, to, 0, cap, cost});
76     edges.push_back((Edge){to, from, 0, 0, -cost});
77     int size = edges.size();
78     G[from].push_back(size - 2);
79     G[to].push_back(size - 1);
80 }
81 
82 int main() {
83     n = read(), m = read(), S = 0, T = n<<1|1;
84     for (int i = 1; i <= n; ++ i) {
85         A[i] = read();
86         addEdge(S, (i<<1)-1, 1, A[i]);
87         addEdge(S, i<<1, 1, 0);
88         addEdge((i<<1)-1, T, 1, 0);
89     }
90     for (int i = 1; i <= m; ++ i) {
91         int u = read(), v = read(), w = read();
92         if (u > v) u ^= v, v ^= u, u ^= v;
93         addEdge(u<<1, (v<<1)-1, 1, w);
94     }
95     n = (n << 1) + 2;
96     printf("%lld\n", minCost());
97     return 0;
98 }

以上是关于SDOI 2010 星际竞速 | 费用流的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1927 [Sdoi2010]星际竞速最小费用最大流

bzoj1927[Sdoi2010]星际竞速 有上下界费用流

P2469 [SDOI2010]星际竞速

[bzoj1927] [Sdoi2010]星际竞速

BZOJ:1927: [Sdoi2010]星际竞速

Bzoj1927星际竞速(费用流)