非常棒非常棒的费用流(线性规划)题目,我暂时不会simplex所以只能用费用流水水
//By Richard
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <ctime>
#define rep(x,y,z) for (int x=(y);(x)<=(z);(x)++)
#define per(x,y,z) for (int x=(y);(x)>=(z);(x)--)
#define log2(x) (31-__builtin_clz(x))
#define mod (int)(1e9+7)
#define inf 0x3f3f3f3f
#define cls(x) memset(x,0,sizeof(x))
#ifdef DEBUG
#define debugdo(X) X
#define debugndo(X)
#define debugout(X) cout<<(#X)<<"="<<(X)<<endl
#else
#define debugdo(X)
#define debugndo(X) X
#define debugout(X)
#endif // debug
#ifdef ONLINE_JUDGE
#define debugdo(X)
#define debugndo(X)
#define debugout(X)
#endif
#define putarray(x,n) rep(iiii,1,n) printf("%d ",x[iiii])
#define mp make_pair
using namespace std;
typedef pair<int,int> pairs;
typedef long long LL;
/////////////////////read4.0////////////////////////////////////
template <typename T>
inline void read(T &x){char ch;x=0;bool flag=false;ch=getchar();while (ch>'9'||ch<'0') {if (ch=='-') flag=true;ch=getchar();}while ((ch<='9'&&ch>='0')){x=x*10+ch-'0';ch=getchar();}if (flag) x*=-1;}
template <typename T>
inline void read(T &x,T &y){read(x);read(y);}
template <typename T>
inline void read(T &x,T &y,T &z){read(x);read(y);read(z);}
/////////////////////graph///////////////////////////////
const int MAXV=1111,MAXE=51111;
struct EDGE
{
int u,v,w,cost;
};
struct GRAPH
{
EDGE edge[MAXE];
int next[MAXE],first[MAXV],cnt;
inline void init()
{
cnt=0;
cls(edge);
cls(next);
memset(first,-1,sizeof(first));
}
inline void addedge(int u,int v,int w,int cost)
{
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].cost=cost;
next[cnt]=first[u];
first[u]=cnt++;
edge[cnt].u=v;
edge[cnt].v=u;
edge[cnt].w=0;
edge[cnt].cost=-cost;
next[cnt]=first[v];
first[v]=cnt++;
}
int distance[MAXV],route[MAXV],maxflow;
bool vis[MAXV];
queue <int> qu;
inline bool spfa(int s,int t)
{
memset(distance,0x3f,sizeof(distance));
memset(route,-1,sizeof(route));
cls(vis);
distance[s]=0;
vis[s]=true;
qu.push(s);
while (!qu.empty())
{
int p=qu.front();
qu.pop();
int q=first[p];
vis[p]=false;
while (q!=-1)
{
if (edge[q].w&&distance[edge[q].v]>distance[p]+edge[q].cost)
{
distance[edge[q].v]=distance[p]+edge[q].cost;
route[edge[q].v]=q;
if (!vis[edge[q].v])
{
qu.push(edge[q].v);
vis[edge[q].v]=true;
}
}
q=next[q];
}
}
if (distance[t]==inf) return false;
return true;
}
int MCMF(int s,int t)
{
int mincost=0,nowflow=0,minflow;
while (spfa(s,t))
{
minflow=inf+1;
int q=route[t];
while (q!=-1)
{
minflow=min(minflow,edge[q].w);
q=route[edge[q].u];
}
nowflow+=minflow;
q=route[t];
while (q!=-1)
{
edge[q].w-=minflow;
edge[q^1].w+=minflow;
q=route[edge[q].u];
}
mincost+=distance[t]*minflow;
}
maxflow=nowflow;
return mincost;
}
}graph;
int n,s,t,a[MAXV],m;
int main()
{
read(n,m);
s=0,t=n+2;
graph.init();
rep(i,1,n) read(a[i]);
int x,y,z;
rep(i,1,m)
{
read(x,y,z);
graph.addedge(x,y+1,inf,z);
}
a[0]=a[n+1]=0;
rep(i,1,n+1)
{
int temp=a[i]-a[i-1];
if (temp>=0) graph.addedge(s,i,temp,0);
else graph.addedge(i,t,-temp,0);
}
rep(i,1,n) graph.addedge(i+1,i,inf,0);
printf("%d\n",graph.MCMF(s,t));
return 0;
}