很犀利的一个道网络流
关键是掌握数学模型。把问题化简为等式等同于网络流的流平衡定理。
解题报告见http://www.byvoid.com/blog/noi-2008-employee/#more-916
代码如下
1 /*
2 * =====================================================================================
3 *
4 * Filename: net.cpp
5 *
6 * Description: network flow
7 *
8 * Version: 1.0
9 * Created: 08/16/2011 01:53:16 PM
10 * Revision: none
11 * Compiler: gcc
12 *
13 * Author: ronaflx
14 * Company: hit-ACM-Group
15 *
16 * =====================================================================================
17 */
18
19 #include <cstdlib>
20 #include <cctype>
21 #include <cstring>
22 #include <iterator>
23 #include <limits>
24 #include <cstdio>
25 #include <cmath>
26 #include <ctime>
27 #include <climits>
28 #include <algorithm>
29 #include <functional>
30 #include <numeric>
31 #include <vector>
32 #include <map>
33 #include <set>
34 #include <queue>
35 #include <stack>
36 #include <bitset>
37 #include <list>
38 #include <string>
39 #include <iostream>
40 #include <sstream>
41 #include <fstream>
42 #include <iomanip>
43 #include <stdexcept>
44 #include <utility>
45 #include <cassert>
46 #include <complex>
47 using namespace std;
48
49 #define LEFT(i) ((i) << 1)
50 #define RIGHT(i) (((i) << 1) | 1)
51 #define MID(i) ((l[i] + r[i]) >> 1)
52 #define CC(i, v) memset(i, v, sizeof(i))
53 #define REP(i, l, n) for(int i = l;i < int(n);++i)
54 #define FOREACH(con, i) for(__typeof(con.begin()) i = con.begin();i != con.end();++i)
55 typedef long long LL;
56
57 typedef int USETYPE;
58 const USETYPE INF = numeric_limits<USETYPE>::max();//<limits>
59 template<typename T = int>
60 class mincost
61 {
62 private:
63 const static int N = 2500;
64 const static int E = 100000;
65 struct edge
66 {
67 int u, v;
68 T cost, cap;
69 edge *nxt;
70 } pool[E], *g[N], *pp, *pree[N];
71 T dist[N];
72
73 bool SPFA(int n,int s, int t)
74 {
75 fill(dist, dist + n, INF);
76 int tail = 0, q[N] = {s};
77 dist[s] = 0;
78 bool vst[N] = {false};
79 vst[s] = true;
80 for(int i = 0; i <= tail; i++)
81 {
82 int u = q[i % n];
83 for(edge *j = g[u]; j != NULL; j= j->nxt)
84 {
85 int v = j->v;
86 if(j->cap && dist[u] != INF && dist[v] > dist[u] + j->cost)
87 {
88 dist[v] = dist[u] + j->cost;
89 pree[v] = j;
90 if(!vst[v])
91 {
92 tail++;
93 q[tail % n] = v;
94 vst[v] = true;
95 }
96 }
97 }
98 vst[u] = false;
99 }
100 return dist[t] < INF;
101 }
102 public:
103 #define OP(i) (((i) - pool) ^ 1)
104 void addedge(int u, int v, T cap, T cost)
105 {
106 pp->u = u, pp->v = v;
107 pp->cost = cost, pp->cap = cap;
108 pp->nxt = g[u],g[u] = pp++;
109 }
110 void initialize()
111 {
112 CC(g, 0);
113 pp = pool;
114 }
115 pair<T, T> mincostflow(int n, int s, int t)
116 {
117 T flow = 0, cost = 0;
118 while(SPFA(n, s, t))
119 {
120 T minf = INF;
121 for(int i = t; i != s; i = pree[i]->u)
122 minf = min(minf, pree[i]->cap);
123 for(int i = t; i != s; i = pree[i]->u)
124 {
125 pree[i]->cap -= minf;
126 pool[OP(pree[i])].cap += minf;
127 cost += minf * pree[i]->cost;
128 }
129 flow += minf;
130 }
131 return make_pair(flow, cost);
132 }
133 };
134 const int N = 1010;
135 int need[N];
136 mincost<int> flow;
137 int main()
138 {
139 int n, m;
140 while(scanf("%d %d", &n, &m) == 2)
141 {
142 int s = 0, t = n + 2;
143 flow.initialize();
144 memset(need, 0, sizeof(need));
145 for(int i = 1;i <= n;i++)
146 scanf("%d", &need[i]);
147 for(int i = 1;i <= n + 1;i++)
148 if(need[i] - need[i - 1] > 0)
149 {
150 flow.addedge(s, i, need[i] - need[i - 1], 0);
151 flow.addedge(i, s, need[i - 1] - need[i], 0);
152 }
153 else
154 {
155 flow.addedge(i, t, need[i - 1] - need[i], 0);
156 flow.addedge(t, i, need[i] - need[i - 1], 0);
157 }
158 for(int i = 0;i < m;i++)
159 {
160 int a, b, c;
161 scanf("%d %d %d", &a, &b, &c);
162 flow.addedge(a, b + 1, INF, c);
163 flow.addedge(b + 1, a, 0, -c);
164 }
165 for(int i = 2;i <= n + 1;i++)
166 {
167 flow.addedge(i, i - 1, INF, 0);
168 flow.addedge(i - 1, i, 0, 0);
169 }
170 printf("%d\n", flow.mincostflow(t + 1, s, t).second);
171 }
172 return 0;
173 }