单纯形 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\n",-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 }
转载请标明出处 http://www.cnblogs.com/cyz666/