zoukankan      html  css  js  c++  java
  • 单纯形 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=0;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 }
    好短啊

    18年来补。

    UOJ的板子题。。应该比较科学了(忽略中间那个assert)

    。还有就是 ,单纯形真的不靠谱,,还要random才能过?。。

     1 #include <bits/stdc++.h>
     2 #define DB long double
     3 using namespace std;
     4 const DB eps=0.000000001;
     5 int n,m,T,k,t,o[45],c[45];
     6 DB tmp[45],a[45][45];
     7 void SWAP(int k,int t){
     8     swap(o[k],c[t]);
     9     DB x=a[k][t]; a[k][t]=1;
    10     for (int j=0;j<=n;++j) a[k][j]/=x;
    11     for (int i=0;i<=m;++i)
    12     if (i!=k){
    13         x=a[i][t]; a[i][t]=0;
    14         for (int j=0;j<=n;++j) a[i][j]-=x*a[k][j];
    15     }
    16 }
    17 int main(){
    18     scanf("%d%d%d",&n,&m,&T);
    19     for (int i=1;i<=n;++i) scanf("%Lf",&tmp[i]);
    20     for (int i=1;i<=n;++i) c[i]=i;
    21     for (int i=1;i<=m;++i){
    22         for (int j=1;j<=n;++j) scanf("%Lf",&a[i][j]);
    23         scanf("%Lf",&a[i][0]); o[i]=i+n;
    24     }
    25     k=-1;
    26     for (int i=1;i<=m;++i)
    27     if (a[i][0]<0&&(k==-1||a[i][0]<a[k][0])) k=i;
    28     if (~k){
    29         ++n; c[n]=n+m;
    30         for (int i=0;i<=m;++i) a[i][n]=-1;
    31         SWAP(k,n);
    32         while (1){
    33             t=-1;
    34             for (int j=n;j;--j)
    35                 if (a[0][j]>eps) {t=j; if (rand()&1) break;}
    36             if (t==-1) break;
    37             k=-1;
    38             for (int i=1;i<=m;++i)
    39             if (a[i][t]>eps)
    40             if (k==-1||a[i][0]/a[i][t]<a[k][0]/a[k][t]) k=i;
    41             SWAP(k,t);
    42         }
    43         if (fabs(a[0][0])>eps){
    44             puts("Infeasible"); return 0;
    45         }
    46         k=t=-1;
    47         for (int i=1;i<=n;++i) if (c[i]==n+m) t=i;
    48         for (int i=1;i<=m;++i) if (o[i]==n+m) k=i;
    49         if (~k){
    50             for (int j=1;j<=n;++j)
    51                 if (fabs(a[k][j])>eps) {t=j; break;}
    52             if (t==-1){
    53                 assert(0); swap(o[k],o[m]);
    54                 for (int j=0;j<=n;++j) swap(a[k][j],a[m][j]);
    55                 --m;
    56             }else{
    57                 SWAP(k,t); swap(c[t],c[n]);
    58                 for (int i=1;i<=m;++i) swap(a[i][t],a[i][n]);
    59                 --n;
    60             }
    61         }else{
    62             swap(c[t],c[n]);
    63             for (int i=1;i<=m;++i) swap(a[i][t],a[i][n]);
    64             --n;
    65         }
    66     }
    67     for (int i=0;i<=n;++i) a[0][i]=0;
    68     for (int i=1;i<=n;++i)
    69     if (c[i]<=n) a[0][i]+=tmp[c[i]];
    70     for (int i=1;i<=m;++i)
    71     if (o[i]<=n)
    72         for (int j=0;j<=n;++j)
    73         a[0][j]-=tmp[o[i]]*a[i][j];
    74     while (1){
    75         t=-1;
    76         for (int j=n;j;--j)
    77             if (a[0][j]>eps) {t=j; if (rand()&1) break;}
    78         if (t==-1) break;
    79         k=-1;
    80         for (int i=1;i<=m;++i)
    81         if (a[i][t]>eps)
    82         if (k==-1||a[i][0]/a[i][t]<a[k][0]/a[k][t]) k=i;
    83         if (k==-1){
    84             puts("Unbounded");
    85             return 0;
    86         }
    87         SWAP(k,t);
    88     }
    89     printf("%.10Lf
    ",-a[0][0]);
    90     if (T){
    91         for (int i=1;i<=n;++i) tmp[c[i]]=0;
    92         for (int i=1;i<=m;++i) tmp[o[i]]=a[i][0];
    93         for (int i=1;i<=n;++i) printf("%.10Lf ",tmp[i]);
    94         puts("");
    95     }
    96     return 0;
    97 }
    天壌を翔る者たち
  • 相关阅读:
    Prime Ring Problem 素数环
    下沙的沙子有几粒?
    小兔的棋盘
    超级楼梯
    一只小蜜蜂...
    变形课
    Buy the Ticket
    How Many Trees?
    通过拦截器来统计每个action的执行时间
    apache+tomcat+session(JK实现方式)
  • 原文地址:https://www.cnblogs.com/cyz666/p/6636193.html
Copyright © 2011-2022 走看看