首页 > 代码库 > 单纯形 BZOJ3112: [Zjoi2013]防守战线

单纯形 BZOJ3112: [Zjoi2013]防守战线

题面自己上网查。

学了一下单纯形。当然 证明什么的 显然是没去学。不然估计就要残废了

上学期已经了解了 什么叫标准型。 听起来高大上 其实没什么

就是加入好多松弛变量+各种*(-1),使得最后成为一般形式:

  给定A[][],求满足A[i][j]*Xj<=A[i][0];(0<i<=n,0<j<=m)

  使A[0][j]*Xj最大的X[];

如果题面中直接得出的条件是A[i][j]*Xj>=A[i][0]; 使 A[0][j]*Xj最小。

  那么就要用对偶定理,变成 A[i][j]*Yi<=A[0][j] 使A[i][0]*Yi最大

    (实际上只要把A转置一下就好了)

  才写了两题单纯形,具体的怎么求Xi之类的 还没学,这里先放代码,之后再补

 

技术分享
 1 #include <bits/stdc++.h>
 2 #define N 1005
 3 #define M 10005
 4 using namespace std;
 5 const double eps=0.00000000001;
 6 const double inf=10000000000000;
 7 double a[N][M]; int n,m,x,y;
 8 void simplex(){
 9     while (1){
10         int x=0,y=0; double mn=inf,t;
11         for (int i=1;i<=m;++i) if (a[0][i]>eps) {y=i; break;} //找一个可以使答案增加的xi 只要系数为正就可以
12         if (!y) return;  //没有了 说明答案已经不能再增加了
13         for (int i=1;i<=n;++i) if (a[i][y]>eps&&a[i][0]/a[i][y]<mn) mn=a[x=i][0]/a[i][y];  //对找到的xi ,求出约束最紧的一条约束
14         if (!x) {a[0][0]=-inf; return;}  //表示 可以无限增加
15         t=a[x][y]; a[x][y]=1;
16         for (int i=1;i<=m;++i) a[x][i]/=t;
17         for (int i=0;i<=n;++i) if (i!=x&&abs(a[i][y])>eps){
18             t=a[i][y]; a[i][y]=0; for (int j=0;j<=m;++j) a[i][j]-=t*a[x][j];
19         }
20     }
21 }
22 int main(){
23     scanf("%d%d",&n,&m);
24     for (int i=1;i<=n;++i) scanf("%lf",&a[i][0]);
25     for (int i=1;i<=m;++i){
26         scanf("%d%d%lf",&x,&y,&a[0][i]);
27         for (int j=x;j<=y;++j) ++a[j][i];
28     }
29     simplex();
30     printf("%.0lf",round(-a[0][0]));
31     return 0;
32 }
好短

 

单纯形 BZOJ3112: [Zjoi2013]防守战线