bzoj 1061 单纯形法,或转化网络流(待补)

1061: [Noi2008]志愿者招募

tags:没搞懂,单纯形法,很数学的感觉。。但又学到一个模板=^=,MDZZ

#include<cstdio>
#include<cmath>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a;i<=b;i++)
#define per(i,b,a) for (int i=b;i>=a;i--)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
typedef long long ll;

const int N=1010, M=10010;
const double inf=1e10, eps=1e-7;
int n, m;
double b[M], c[N], cof[M][N], ans;
void pivot(int id, int pos)
{
    b[id]/=cof[id][pos];
    cof[id][pos]=1/cof[id][pos];
    for(int i=1; i<=n; i++) if(i!=pos) cof[id][i]*=cof[id][pos];
    for(int i=1; i<=m; i++) if(i!=id && fabs(cof[i][pos])>eps) {
        b[i]-=cof[i][pos]*b[id];
        for(int j=1; j<=n; j++) if(j!=pos)
            cof[i][j]-=cof[i][pos]*cof[id][j];
        cof[i][pos]= -cof[i][pos]*cof[id][pos];
    }
    ans+=c[pos]*b[id];
    for(int i=1; i<=n; i++) if(i!=pos) c[i]-=c[pos]*cof[id][i];
    c[pos]= -c[pos]*cof[id][pos];
}
double simplex()
{
    while(1) {
        int pos, id;
        for(pos=1; pos<=n; pos++) if(c[pos]>eps) break;
        if(pos==n+1) return ans;
        double temp=inf;
        for(int i=1; i<=m; i++) if(cof[i][pos]>eps && b[i]/cof[i][pos]<temp)
            temp=b[i]/cof[i][pos], id=i;
        if(temp==inf) return inf;
        pivot(id, pos);
    }
}

int main()
{
    scanf("%d %d", &n, &m);
    rep(i,1,n) scanf("%lf", &c[i]);
    int x, y;
    rep(i,1,m) {
        scanf("%d %d", &x, &y);
        rep(j,x,y) cof[i][j]=1;
        scanf("%lf", &b[i]);
    }
    printf("%d\n", int(simplex()+0.5));

    return 0;
}
posted @ 2017-03-03 15:17  v9fly  阅读(397)  评论(3编辑  收藏  举报