title
BZOJ 1061
Description
After the successful Olympic bid, boob through unremitting efforts, has finally become director of BOCOG subsidiary HR department. Bubu took office just ran into a problem: the recruitment of a number of short-term volunteers for the upcoming launch of the new Olympic project. After estimating that the project requires N days to complete, with the first day at least i Ai individual. Bubu by understanding that a total of M class volunteers can be recruited. Wherein the i-type Si from the first day to work on Day Ti, Ci recruitment costs per person. New broom sweeps clean, well done to their jobs, boob to exhaust less cost of recruiting enough volunteers, but this is not his specialty! So Bubu found you, I hope you help him design an optimal recruitment programs.
Input
The first line contains two integers N, M, indicating the type and number of days to complete the project can recruit volunteers. The next line contains N non-negative integers, it represents the required minimum number of volunteers per day. The next M rows each line contains three integers Si, Ti, Ci, meanings as described above. For convenience, we can say that the number of each type are an infinite number of volunteers.
Output
Only contains an integer that represents the total cost of the optimal solution of your design.
Sample Input
3 3
2 3 4
1 2 2
2 3 5
3 3 2
Sample Output
14
HINT
1 ≤ N ≤ 1000,1 ≤ M ≤ 10000, the title of the other data involved does not exceed 2 ^ 31-1.
analysis
This question is to write good problem solution.
At first model I have in mind is active sink lower bound of network flow, ah, will not be processed, it stunned an hour.
Afternoon after school to the room, ask the , found built a small drawing skills, really wonderful!
My original idea is to first day of the first between the sky and the edge, but certainly better than the first capacity needed day large number of volunteers, so a bit uncomfortable.
Then, this little trick is this:
we observe: For convenience, we can say that the number of each type are an infinite number of volunteers.
Ah, we put all the sides to capacity
Number of volunteers in order to meet the required minimum daily
, to use
as their capacity, forced into lower bound upper bound, that we write the most common network flow.
There is also a thinking skills: we will all edges of the capacity vested endpoint his left, so if we want to ensure that the first the number of volunteers needed days, we need to build a point, but we must also ensure the capacity and the meeting point of that edge is even , so we need to build a , and even capacity , The cost of edge.
Then the other on the no need to say, it's all routine.
code
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+10,inf=0x3f3f3f3f;
char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
template<typename T>inline void write(T x)
{
if (!x) { putchar('0'); return ; }
if (x<0) putchar('-'), x=-x;
T num=0, ch[20];
while (x) ch[++num]=x%10+48, x/=10;
while (num) putchar(ch[num--]);
}
int ver[maxn<<1],edge[maxn<<1],Next[maxn<<1],cost[maxn<<1],head[maxn],len=1;
inline void add(int x,int y,int z,int c)
{
ver[++len]=y,edge[len]=z,cost[len]=c,Next[len]=head[x],head[x]=len;
ver[++len]=x,edge[len]=0,cost[len]=-c,Next[len]=head[y],head[y]=len;
}
int s,t;
int dist[maxn],incf[maxn],pre[maxn];
bool vis[maxn];
inline bool spfa()
{
memset(dist,0x3f,sizeof(dist));
memset(vis,0,sizeof(vis));
queue<int>q;q.push(s);
dist[s]=0,vis[s]=1,incf[s]=1<<30;
while (!q.empty())
{
int x=q.front();
q.pop();
vis[x]=0;
for (int i=head[x]; i; i=Next[i])
{
if (!edge[i]) continue;
int y=ver[i];
if (dist[y]>dist[x]+cost[i])
{
dist[y]=dist[x]+cost[i];
incf[y]=min(incf[x],edge[i]);
pre[y]=i;
if (!vis[y]) q.push(y),vis[y]=1;
}
}
}
if (dist[t]==inf) return false;
else return true;
}
long long maxflow,ans;
inline void update()
{
int x=t;
while (x!=s)
{
int i=pre[x];
edge[i]-=incf[t];
edge[i^1]+=incf[t];
x=ver[i^1];
}
maxflow+=incf[t];
ans+=dist[t]*incf[t];
}
int main()
{
int n,m;
read(n);read(m);
s=0,t=n+m+1;
for (int i=1,x; i<=n; ++i) read(x),add(i,i+1,inf-x,0);//将下界网络流转化为上届网络流的一个神奇操作
add(s,1,inf,0),add(n+1,t,inf,0);
for (int i=1,si,ti,ci; i<=m; ++i) read(si),read(ti),read(ci),add(si,ti+1,inf,ci);
while (spfa()) update();
write(ans);
return 0;
}