1. 程式人生 > >BZOJ3112: [Zjoi2013]防守戰線(單純形+對偶原理)

BZOJ3112: [Zjoi2013]防守戰線(單純形+對偶原理)

傳送門

題解:
單純形立水之。

#include <bits/stdc++.h>
using namespace std;
typedef double DB;

const int RLEN=1<<18|1;
inline char nc() {
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
	char ch=
nc(); int i=0,f=1; while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();} while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();} return i*f; } const DB eps=1e-5; const int N=1e3+50, M=1e4+50; int n,m,q[M]; double a[N][M]; inline void pivot(int l,int e) { q[0]=0; double t=a[l][e]; a[l][e]=1; for
(int i=0;i<=m;i++) if(fabs(a[l][i]/=t)>eps) q[++q[0]]=i; for(int i=0;i<=n;i++) if(i!=l && fabs(a[i][e])>eps) { double t=a[i][e]; a[i][e]=0; for(int j=1;j<=q[0];j++) a[i][q[j]]-=t*a[l][q[j]]; } } inline void simplex() { while(1) { int l=0,e=0; for(int i=1;i<=m;i++) if
(a[0][i]>eps) {e=i; break;} if(!e) break; double mn=1e80; for(int i=1;i<=n;i++) if(a[i][e]>eps && a[i][0]/a[i][e]<mn) mn=a[i][0]/a[i][e], l=i; if(!l) {puts("Unbounded"); break;} pivot(l,e); } } int main() { n=rd(), m=rd(); for(int i=1;i<=n;i++) a[i][0]=rd(); for(int i=1;i<=m;i++) { int l=rd(), r=rd(); a[0][i]=rd(); for(int j=l;j<=r;j++) a[j][i]=1; } simplex(); printf("%.f\n",-a[0][0]); }