【BZOJ】【P3265】【志愿者招募加强版】【题解】【单纯形法】

来源:互联网 发布:mac装双系统win分区 编辑:程序博客网 时间:2024/05/21 22:45

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3265

读了一天算导,成功yy出单纯形~~

Code:

#include<bits/stdc++.h>using namespace std;const int maxn=10010;const int maxm=1010;const double eps=1e-8;double a[maxn][maxm];int n,m;int dcmp(double x){if(fabs(x)<eps)return 0;return x>0?1:-1;}double simplex(bool f);void pivot(int l,int e,bool f){for(int i=0;i<=m+f;i++){if(i==e)continue;a[l][i]/=a[l][e];}a[l][e]=1/a[l][e];for(int i=0;i<=n+f;i++){if(i==l)continue;for(int j=0;j<=m+f;j++){if(j==e)continue;a[i][j]-=a[i][e]*a[l][j];}a[i][e]*=-a[l][e];}}void init(){int pos=-1;double minn=1e10;for(int i=1;i<=n;i++)if(dcmp(minn-a[i][0])==1)minn=a[i][0],pos=i;if(dcmp(minn)>=0)return;for(int i=0;i<=m;i++)swap(a[0][i],a[n+1][i]);for(int i=0;i<=n;i++)a[i][m+1]=-1;pivot(pos,m+1,1);if(!dcmp(simplex(1))){for(int i=1;i<=m+1;i++)if(!dcmp(a[0][i]+1)){pos=i;break;}for(int i=0;i<=m+1;i++)swap(a[0][i],a[n+1][i]);for(int i=0;i<=n+1;i++)swap(a[i][pos],a[i][m+1]);}else puts("Can't solve!!");}double simplex(bool f){for(;;){int pos=-1,l,e;double minn=0;for(int i=1;i<=m+f;i++)if(dcmp(a[0][i]-minn)==1)minn=a[0][i],pos=i;if(!~pos)return -a[0][0];e=pos;pos=-1;minn=1e10;for(int i=1;i<=n;i++)if(dcmp(a[i][e])==1&&dcmp(a[i][0]/a[i][e]-minn)==-1)minn=a[i][0]/a[i][e],pos=i;if(!~pos){printf("INF!!\n");return 1e10;}l=pos;pivot(l,e,f);}}int main(){scanf("%d%d",&m,&n);for(int i=1;i<=m;i++)scanf("%lf",&a[0][i]);for(int i=1;i<=n;i++){int k;scanf("%d",&k);while(k--){int l,r;scanf("%d%d",&l,&r);for(int j=l;j<=r;j++)a[i][j]=1;}scanf("%d",&k);a[i][0]=k;}init();int ans=simplex(0)+.5;printf("%d\n",ans);return 0;}


0 0
原创粉丝点击