单纯形模板
板子来自神犇zzq
1 #include <ctime> 2 #include <cmath> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <algorithm> 7 #define N1 111 8 #define dd double 9 #define ld long double 10 #define ll long long 11 #define ull unsigned long long 12 using namespace std; 13 14 const ld eps=1e-9; 15 const int inf=0x3f3f3f3f; 16 int gint() 17 { 18 int ret=0,fh=1;char c=getchar(); 19 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 20 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 21 return ret*fh; 22 } 23 24 int n,m,T; 25 int id[N1]; 26 ld a[N1][N1],val[N1]; 27 28 int dcmp(ld x) 29 { 30 if(x<-eps) return -1; 31 if(x>eps) return 1; 32 return 0; 33 } 34 void pivot(int r,int c) 35 { 36 swap(id[r+n],id[c]); 37 int i,j; 38 ld x=-a[r][c]; a[r][c]=-1; 39 for(i=0;i<=n;i++) a[r][i]/=x; 40 for(i=0;i<=m;i++) 41 { 42 if(!dcmp(a[i][c])||i==r) continue; 43 x=a[i][c]; a[i][c]=0; 44 for(j=0;j<=n;j++) a[i][j]+=x*a[r][j]; 45 } 46 } 47 void solve() 48 { 49 int i,j,x,y,fl; 50 for(i=1;i<=n;i++) id[i]=i; 51 while(1) 52 { 53 x=0,y=0; 54 for(i=1;i<=m;i++) 55 if( dcmp(a[i][0])<0 && (!x||rand()&1) ) x=i; 56 if(!x) break; 57 for(i=1;i<=n;i++) 58 if( dcmp(a[x][i])>0 && (!y||rand()&1) ) y=i; 59 if(!y){ puts("Infeasible"); return; } 60 pivot(x,y); 61 } 62 ld w,t; 63 while(1) 64 { 65 x=0,y=0; 66 for(i=1;i<=n;i++) 67 if( dcmp(a[0][i])>0 && (!x||rand()&1) ) x=i; 68 if(!x) break; 69 w=1e18; t=0; 70 for(i=1;i<=m;i++) 71 { 72 if( dcmp(a[i][x])>=0 ) continue; 73 t=-a[i][0]/a[i][x]; 74 if(t<w||!y) y=i, w=t; 75 } 76 if(!y){ puts("Unbounded"); return; } 77 pivot(y,x); 78 } 79 printf("%.8Lf\n",a[0][0]); 80 if(!T) return; 81 for(i=1;i<=n;i++) val[id[i]]=0; 82 for(i=n+1;i<=n+m;i++) val[id[i]]=a[i-n][0]; 83 for(i=1;i<=n;i++) printf("%.8Lf ",val[i]); 84 puts(""); 85 } 86 87 int main() 88 { 89 srand(time(NULL)); 90 int i,j; 91 scanf("%d%d%d",&n,&m,&T); 92 for(i=1;i<=n;i++) scanf("%Lf",&a[0][i]); 93 for(i=1;i<=m;i++) 94 { 95 for(j=1;j<=n;j++) scanf("%Lf",&a[i][j]), a[i][j]*=-1; 96 scanf("%Lf",&a[i][0]); 97 } 98 solve(); 99 return 0; 100 }