您的位置:首页 > 其它

bzoj 3265 志愿者招募加强版 (单纯形)

2016-04-05 19:10 344 查看
这里对原问题进行了对偶求解

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;

#define N 520
#define M 200020
#define inf 0x3f3f3f3f
#define eps 1e-8

double A[10100][1020], b[10100], c[1020];
int n, m;
double ans = 0;

void pivot(int l, int e) {
b[l] /= A[l][e];
for(int i = 1; i <= n; ++i) {
if(i != e) {
A[l][i] /= A[l][e];
}
}
A[l][e] = 1 / A[l][e];
for(int i = 1; i <= m; ++i) {
if(i != l && fabs(A[i][e]) > eps) {
b[i] -= A[i][e] * b[l];
for(int j = 1; j <= n; ++j) {
if(j != e) {
A[i][j] -= A[i][e] * A[l][j];
}
}
A[i][e] = -A[i][e] * A[l][e];
}
}
ans += c[e] * b[l];
for(int i = 1; i <= n; ++i) {
if(i != e) {
c[i] -= c[e] * A[l][i];
}
}
c[e] = -c[e] * A[l][e];
}
void simplex() {
while(1) {
int e = -1;
for(int i = 1; i <= n; ++i) {
if(c[i] > eps) {
e = i;
break;
}
}
if(e == -1) return;
double tmp = 1e10;
int l = -1;
for(int i = 1; i <= m; ++i) {
if(A[i][e] > eps && b[i] / A[i][e] < tmp) {
tmp = b[i] / A[i][e], l = i;
}
}
if(l == -1) return;
pivot(l, e);
}
}

int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) {
scanf("%lf", &c[i]);
}
for(int i = 1; i <= m; ++i) {
int s, t, c;
int k;
scanf("%d", &k);
while(k--) {
scanf("%d%d", &s, &t);
for(int j = s; j <= t; ++j) {
A[i][j] = 1;
}
}
scanf("%d", &c);
b[i] = c;
}
simplex();
printf("%d\n", (int)(ans + 0.5));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: