= =跟上一道基本相同,可以单纯形法解线性规划,也可以费用流.
写费用流的话建图就是一般的线性规划转费用流的套路,加上基变量,然后化成等式,每个下式减上式之后可以化成表示流量平衡的等式,然后根据等式建图就好了,跑一个最小费用最大流.
写单纯形没有写网络流好理解,单纯形的话因为这是最小化费用的,首先要转化成对偶问题(我到现在也不能理解对偶问题QAQ),我的理解就是把原本的B[i]写成c[i],c[i]写成B[i],n写成m,m写成n,然后xjb搞一搞就好了,而且本来也感觉单纯形这个模板凭理解很难打= =,其实背的话更难,因为背模板其实都是建立在理解的基础之上的,其实就是写的熟练罢了,不理解的话真的特别容易写错,跟自适应辛普森积分一样(捂脸),mdzz好的我承认我是数学不好.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1e3+5,M=1e4+5;
const double eps=1e-7,inf=1e10;
double ans,A[M][N],B[M],c[N];
int n,m,L,R;
inline void pivot(int l,int e)
{
B[l]/=A[l][e];
for (int i=1;i<=n;++i)
if (i!=e)A[l][i]/=A[l][e];
A[l][e]=1/A[l][e];
for (int i;i<=m;++i)
if (i!=l&&fabs(A[i][e])>eps)
{
B[i]-=B[l]*A[i][e];
for (int j=1;j<=n;j++)
if (j!=e)A[i][j]-=A[i][e]*A[l][j];
A[i][e]=-A[l][e]*A[i][e];
}
ans+=c[e]*B[l];
for(int i=1;i<=n;++i)
if (i!=e)c[i]-=c[e]*A[l][i];
c[e]=-c[e]*A[l][e];
}
inline void simplex()
{
int e;
while(1)
{
for (e=1;e<=n;e++)
if (c[e]>eps)break;
if (e==n+1) break;
double t,delta=inf;int l;
for (int i=1;i<=m;++i)
if (A[i][e]>eps&&(t=B[i]/A[i][e])<delta)
l=i,delta=t;
pivot(l,e);
}
}
int main()
{
cin>>n>>m;
for (int i=1;i<=n;++i)
scanf("%lf",&c[i]);
for (int i=1;i<=m;++i)
{
scanf("%d%d%lf",&L,&R,&B[i]);
for (int j=L;j<=R;++j)
A[i][j]=1;
}
simplex();
printf("%.0lf",ans);
}