【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;
}
读了一天算导,成功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_P3265 志愿者招募加强版(最小费用最大流)
- 【BZOJ3265】志愿者招募加强版【单纯形法】
- 【BZOJ1061/3265】[Noi2008]志愿者招募/志愿者招募加强版 单纯形法
- BZOJ 3265: 志愿者招募加强版 [单纯形法]
- 【BZOJ3265】志愿者招募加强版 线性规划 单纯形法 对偶原理
- 【bzoj3265】志愿者招募加强版 单纯形
- BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记看另一篇吧】
- BZOJ 3265 志愿者招募加强版 单纯形
- [BZOJ3265]志愿者招募加强版
- BZOJ 3265 志愿者招募(BZOJ 1061)加强版 && BZOJ 3112 [Zjoi2013]防守战线 单纯形
- BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]
- bzoj3265 志愿者招募加强版(线性规划)
- 【BZOJ1061】[Noi2008]志愿者招募【单纯形法】
- bzoj1061、3265 志愿者招募【单纯形法】
- [线性规划 对偶原理 单纯形] BZOJ 3265 志愿者招募加强版
- bzoj 3265: 志愿者招募加强版 (单纯形)
- [BZOJ3265]志愿者招募加强版(单纯形)
- bzoj 3265 志愿者招募加强版 (单纯形)
- 【bzoj1061】 Noi20 4000 08—志愿者招募
- BZOJ 3265 志愿者招募增强版 单