设 \(i\) 点表示第 \(i\) 天
志愿者 \((s_i,t_i,c_i)\),建边 \(s_i \to t_i +1\),费用 \(c_i\),流量无限
\(i\) 向 \(i+1\) 连边 \(inf - a[i]\),费用为\(0\)
\(S \to 1, n+1 \to T\),费用为 \(0\),容量 \(inf\)
#include
using namespace std;
#define int long long
namespace mcmf {
const int maxn = 50005;
const int maxm = 300005;
const int inf = 1e+9;
struct R {
int to, nxt, co, va;
} e[maxm * 2 + 5];
int q[maxm + 5], l, r;
int vs[maxn + 5], nxt[maxn + 5], d[maxn + 5];
int h[maxn + 5], cnt = 1;
int n, m;
int ans;
void add(int u, int v, int w, int c) {
cnt++;
e[cnt] = (R){ v, h[u], w, c };
h[u] = cnt;
return;
}
int Spfa(int s, int t) {
for (int i = 1; i <= n; i++) {
nxt[i] = -1;
d[i] = inf;
vs[i] = 0;
}
l = r = 1;
q[l] = s;
d[s] = 0;
vs[s] = 1;
while (l <= r) {
int u = q[l];
l++;
vs[u] = 0;
for (int i = h[u]; i; i = e[i].nxt) {
int v = e[i].to;
int w = e[i].va;
if (e[i].co && d[u] + w < d[v]) {
nxt[v] = i;
d[v] = d[u] + w;
if (!vs[v]) {
q[++r] = v;
vs[v] = 1;
}
}
}
}
if (d[t] < inf)
return 1;
return 0;
}
void Mco(int s, int t) {
int flow = 0, cost = 0;
while (Spfa(s, t)) {
//cout<<"!";
int mn = inf;
for (int p = nxt[t]; p != -1; p = nxt[e[p ^ 1].to]) mn = min(e[p].co, mn);
for (int p = nxt[t]; p != -1; p = nxt[e[p ^ 1].to]) {
e[p].co -= mn;
e[p ^ 1].co += mn;
}
flow += mn;
cost += mn * d[t];
//cout<<"?";
}
ans = cost;
//cout<>n>>m;
for(int i=1;i<=n;i++) cin>>a[i], mk(i,i+1,inf-a[i],0);
mcmf::n = n+3;
mk(n+2,1,inf,0);
mk(n+1,n+3,inf,0);
for(int i=1;i<=m;i++) {
cin>>s[i]>>t[i]>>c[i];
mk(s[i],t[i]+1,inf,c[i]);
}
mcmf::Mco(n+2,n+3);
cout<