[BZOJ 3112][Zjoi2013]防守战线:单纯形

点击这里查看原题
(那个链接里没有题面,题面在这里

单纯形裸题,因为题目中是求最大值,因此需要使用对偶原理

/*
User:Small
Language:C++
Problem No.:3112
*/
#include<bits/stdc++.h>
#define ll long long
#define inf 999999999
using namespace std;
const double eps=1e-6;
int n,m;
double c[10005],b[1005],cof[1005][10005];
void pivot(int in,int out,double &res){
    b[out]/=cof[out][in];
    for(int i=1;i<=n;i++) if(i!=in) cof[out][i]/=cof[out][in];
    cof[out][in]=1/cof[out][in];
    for(int i=1;i<=m;i++) if(i!=out&&fabs(cof[i][in])>eps){
        for(int j=1;j<=n;j++) if(j!=in) cof[i][j]-=cof[i][in]*cof[out][j];
        b[i]-=cof[i][in]*b[out];
        cof[i][in]=-cof[i][in]*cof[out][in];
    }
    res+=c[in]*b[out];
    for(int i=1;i<=n;i++) if(i!=in) c[i]-=cof[out][i]*c[in];
    c[in]=-c[in]*cof[out][in];
}   
double simplex(){
    double res=0;
    while(1){
        int in,out;
        for(in=1;in<=n;in++) if(c[in]>eps) break;
        if(in==n+1) break;
        double tmp=inf;
        for(int i=1;i<=m;i++) if(cof[i][in]>eps&&b[i]/cof[i][in]<tmp)
            tmp=b[i]/cof[i][in],out=i;
        if(tmp==inf) return inf;
        pivot(in,out,res);
    }
    return res;
}
int main(){
    freopen("data.in","r",stdin);//
    scanf("%d%d",&m,&n);
    for(int i=1;i<=m;i++){
        scanf("%lf",&b[i]);
    }
    for(int i=1;i<=n;i++){
        int l,r;
        scanf("%d%d%lf",&l,&r,&c[i]);
        for(int j=l;j<=r;j++) cof[j][i]=1;
    }
    printf("%d\n",(int)(simplex()+0.5));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/SmallSXJ/article/details/73292523