BZOJ 3112 防守战线

单纯形应该做的事情请不要让网络流去做!!!

线性规划表达式列出来和08年国赛一样的处理方法 , 对偶+稀疏矩阵优化可解(而且 , 数据范围都是一样的)

单纯形的实现方法可以参见我的另一篇博客 , 单纯形法的初探

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <cassert>

using namespace std;
const int maxn = 1100;
const int maxm = 11000;
const double INF = 1e10;
const double eps = 1e-10;

int dcmp(double a) { return fabs(a)<eps?0:a<0?-1:1; }

int n , m;
double a[maxn][maxm] , b[maxm][maxn];

void dualize()
{
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j] = b[j][i];
}

void pivot(int l , int e)
{
    for(int i=1;i<=n;i++) if(i!=l && dcmp(a[i][e]))
    {
        for(int j=1;j<=m;j++) if(j!=e) a[i][j] -= a[i][e] / a[l][e] * a[l][j];
        a[i][e] /= -a[l][e];
    }

    for(int i=1;i<=m;i++) if(i!=e) a[l][i] /= a[l][e]; a[l][e] = 1/a[l][e];
}

double simplex()
{
    double mn;
    int l , e;
    while(true)
    {
        for(e=1;e<m;e++) if(dcmp(a[n][e]) > 0) break;

        if(e == m) return a[n][m];

        mn = INF;
        for(int i=1;i<n;i++) if(dcmp(a[i][e]) > 0 && mn > a[i][m]/a[i][e]) mn = a[l=i][m]/a[i][e];

        if(mn == INF) return INF;
        pivot(l, e);
    }
}

int main(int argc, char *argv[]) {

    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%lf" , &b[m+1][i]);

    for(int i=1 , l , r , k;i<=m;i++)
    {
        scanf("%d%d%d" , &l , &r , &k);
        for(;l<=r;l++) b[i][l] = 1;
        b[i][n+1] = k;
    }

    ++n;  ++m;
    dualize();

    cout<<int(-simplex()+0.5)<<endl;

    return 0;
}

你可能感兴趣的:(线性规划)