您的位置:首页 > 其它

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

2014-08-04 14:09 316 查看
传送门: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  省选 bzoj