[BZOJ 3112][ZJOI 2013]防守战线

来源:互联网 发布:程序员教程第三版下载 编辑:程序博客网 时间:2024/04/29 22:16

题目戳[这]http://blog.csdn.net/PoPoQQQ/article/details/44312949

单纯形法

#include <bits/stdc++.h>#define maxn 1010using 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;}
0 0