[BZOJ 3112][ZJOI 2013]防守戰線

題目戳[這]http://blog.csdn.net/PoPoQQQ/article/details/44312949

單純形法

#include <bits/stdc++.h>
#define maxn 1010
using namespace std;

int n, m;

double a[maxn][maxn * 10];
double b[maxn * 10], c[maxn * 10], v;

void rotate(int e, int f){
    b[f] /= a[f][e];
    for(int i = 1; i <= n; i ++)
        if(i != e) a[f][i] /= a[f][e];
    a[f][e] = 1.0 / a[f][e];

    for(int i = 1; i <= m; i ++){
        if(i == f || a[i][e] == 0)continue;
        b[i] -= a[i][e] * b[f];
        for(int j = 1; j <= n; j ++){
            if(j == e)continue;
            a[i][j] -= a[i][e] * a[f][j];
        }
        a[i][e] = -a[i][e] * a[f][e];
    }

    v += c[e] * b[f];
    for(int i = 1; i <= n;i ++)
        if(i != e)c[i] -= c[e] * a[f][i];
    c[e] = -c[e] * a[f][e];
}


double solve(){
    int f, e, i;
    while(true){
        for(e = 0, i = 1; i <= n; i ++)
            if(c[i] > 0){e = i;break;}
        if(e == 0)return v;
        double lim = 1e12;
        for(i = 1; i <= m; i ++)
            if(a[i][e] > 0 && b[i] / a[i][e] < lim)
                f = i, lim = b[i] / a[i][e];
        rotate(e, f);
    }
}

int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++)
        scanf("%lf", &b[i]);
    int L, R;
    for(int i = 1; i <= m; i ++){
        scanf("%d%d%lf", &L, &R, &c[i]);
        for(int j = L; j <= R; j ++)
            a[j][i] = 1;
    }
    swap(n, m);
    //n個變量,m個約束條件
    printf("%d", (int)(solve() + 0.1));
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章