。这个题要是想用费用流写的话就太难了。
所以就要考虑统筹学的另一个工具--单纯形
实际上。很多网络流解决的都是线性规划的问题,,这些问题很多都可以用单纯形解
关于单纯形的学习资料网上很详细了。。这里就说一些代码实现上的小技巧
1、 换完基变量和非基变量,原来非基变量的位置直接赋值为基变量的值
2、操作的形式是 Xn+i + a1*X1 + a2* X2 + a3*X3 = bi
带入的形式是 X1 = bi/a1 - Xn+i / a1 - a2* X2 / a1 - a3*X3 / a1
3、注意eps
4、这个题是对偶问题,,需要将原矩阵A 转置 b、c互换。。。。。。。
码:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define eps 1e-7
double b[10005],a[10005][1005],c[1005],ans;
int n,m,i,j,x,y;
void pvt(int o,int wz)
{//cout<<endl<<o<<" "<<wz<<endl;
int i,j;
b[wz]/=a[wz][o];
for(i=1;i<=n;i++)
if(i!=o)
a[wz][i]/=a[wz][o];
a[wz][o]=1.0/a[wz][o];
for(i=1;i<=m;i++)
if(i!=wz&&fabs(a[i][o])>eps)
{
b[i]-=b[wz]*a[i][o];
// cout<<" "<<i<<" ";
for(j=1;j<=n;j++)
if(j!=o)
a[i][j]-=a[wz][j]*a[i][o];
a[i][o]=-a[i][o]*a[wz][o];// cout<<a[i][o]<<" ";
}//cout<<endl;
ans+=b[wz]*c[o];
// cout<<ans<<" ";
for(i=1;i<=n;i++)
if(i!=o)
c[i]-=c[o]*a[wz][i];
c[o]=-a[wz][o]*c[o];
}
void smp()
{
while(1)
{
int e,lin;
for(e=1;e<=n;e++)if(c[e]>eps)break;//找还没有解决的点
if(e==n+1)break;
// cout<<endl<<e<<endl;
double o=1e10;
for(i=1;i<=m;i++)
if(a[i][e]>eps&&(b[i]/a[i][e])<o)//找最小的 约束
{
o=(b[i]/a[i][e]);
lin=i;
}
// cout<<" "<<b[lin]<<" "<<a[lin][e];
pvt(e,lin);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%lf",&c[i]);
for(i=1;i<=m;i++)
{
scanf("%d%d%lf",&x,&y,&b[i]);
for(j=x;j<=y;j++)
a[i][j]=1;
}
//for(i=1;i<=n;i++)printf("%.1lf ",c[i]);
smp();
printf("%.0lf",ans);
}