2017.10.8 志愿者招募 失败总结
2017-10-08 15:24
204 查看
。这个题要是想用费用流写的话就太难了。
所以就要考虑统筹学的另一个工具--单纯形
实际上。很多网络流解决的都是线性规划的问题,,这些问题很多都可以用单纯形解
关于单纯形的学习资料网上很详细了。。这里就说一些代码实现上的小技巧
1、 换完基变量和非基变量,原来非基变量的位置直接赋值为基变量的值
2、操作的形式是 Xn+i + a1*X1 + a2* X2 + a3*X3 = bi
带入的形式是 X1 = bi/a1 - Xn+i / a1 - a2* X2 / a1 - a3*X3 / a1
3、注意eps
4、这个题是对偶问题,,需要将原矩阵A 转置 b、c互换。。。。。。。
码:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define eps 1e-7
double b[10005],a[10005][1005],c[1005],ans;
int n,m,i,j,x,y;
void pvt(int o,int wz)
{//cout<<endl<<o<<" "<<wz<<endl;
int i,j;
b[wz]/=a[wz][o];
for(i=1;i<=n;i++)
if(i!=o)
a[wz][i]/=a[wz][o];
a[wz][o]=1.0/a[wz][o];
for(i=1;i<=m;i++)
if(i!=wz&&fabs(a[i][o])>eps)
{
b[i]-=b[wz]*a[i][o];
// cout<<" "<<i<<" ";
for(j=1;j<=n;j++)
if(j!=o)
a[i][j]-=a[wz][j]*a[i][o];
a[i][o]=-a[i][o]*a[wz][o];// cout<<a[i][o]<<" ";
}//cout<<endl;
ans+=b[wz]*c[o];
// cout<<ans<<" ";
for(i=1;i<=n;i++)
if(i!=o)
c[i]-=c[o]*a[wz][i];
c[o]=-a[wz][o]*c[o];
}
void smp()
{
while(1)
{
int e,lin;
for(e=1;e<=n;e++)if(c[e]>eps)break;//找还没有解决的点
if(e==n+1)break;
// cout<<endl<<e<<endl;
double o=1e10;
for(i=1;i<=m;i++)
if(a[i][e]>eps&&(b[i]/a[i][e])<o)//找最小的 约束
{
o=(b[i]/a[i][e]);
lin=i;
}
// cout<<" "<<b[lin]<<" "<<a[lin][e];
pvt(e,lin);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%lf",&c[i]);
for(i=1;i<=m;i++)
{
scanf("%d%d%lf",&x,&y,&b[i]);
for(j=x;j<=y;j++)
a[i][j]=1;
}
//for(i=1;i<=n;i++)printf("%.1lf ",c[i]);
smp();
printf("%.0lf",ans);
}
所以就要考虑统筹学的另一个工具--单纯形
实际上。很多网络流解决的都是线性规划的问题,,这些问题很多都可以用单纯形解
关于单纯形的学习资料网上很详细了。。这里就说一些代码实现上的小技巧
1、 换完基变量和非基变量,原来非基变量的位置直接赋值为基变量的值
2、操作的形式是 Xn+i + a1*X1 + a2* X2 + a3*X3 = bi
带入的形式是 X1 = bi/a1 - Xn+i / a1 - a2* X2 / a1 - a3*X3 / a1
3、注意eps
4、这个题是对偶问题,,需要将原矩阵A 转置 b、c互换。。。。。。。
码:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define eps 1e-7
double b[10005],a[10005][1005],c[1005],ans;
int n,m,i,j,x,y;
void pvt(int o,int wz)
{//cout<<endl<<o<<" "<<wz<<endl;
int i,j;
b[wz]/=a[wz][o];
for(i=1;i<=n;i++)
if(i!=o)
a[wz][i]/=a[wz][o];
a[wz][o]=1.0/a[wz][o];
for(i=1;i<=m;i++)
if(i!=wz&&fabs(a[i][o])>eps)
{
b[i]-=b[wz]*a[i][o];
// cout<<" "<<i<<" ";
for(j=1;j<=n;j++)
if(j!=o)
a[i][j]-=a[wz][j]*a[i][o];
a[i][o]=-a[i][o]*a[wz][o];// cout<<a[i][o]<<" ";
}//cout<<endl;
ans+=b[wz]*c[o];
// cout<<ans<<" ";
for(i=1;i<=n;i++)
if(i!=o)
c[i]-=c[o]*a[wz][i];
c[o]=-a[wz][o]*c[o];
}
void smp()
{
while(1)
{
int e,lin;
for(e=1;e<=n;e++)if(c[e]>eps)break;//找还没有解决的点
if(e==n+1)break;
// cout<<endl<<e<<endl;
double o=1e10;
for(i=1;i<=m;i++)
if(a[i][e]>eps&&(b[i]/a[i][e])<o)//找最小的 约束
{
o=(b[i]/a[i][e]);
lin=i;
}
// cout<<" "<<b[lin]<<" "<<a[lin][e];
pvt(e,lin);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%lf",&c[i]);
for(i=1;i<=m;i++)
{
scanf("%d%d%lf",&x,&y,&b[i]);
for(j=x;j<=y;j++)
a[i][j]=1;
}
//for(i=1;i<=n;i++)printf("%.1lf ",c[i]);
smp();
printf("%.0lf",ans);
}
相关文章推荐
- 闹钟失败之总结
- SkinMagic使用方法总结--SetSingleDialogSkin断言失败
- 总结 Xap 包装失败。引发类型为“System.OutOfMemoryException”的异常 的解决方案
- 盲目自信、能力不足、年少轻狂,这是我创业失败后总结的3条血泪事实
- 【费用流|单纯形】BZOJ1061 [Noi2008]志愿者招募
- [BZOJ1061][NOI2008]志愿者招募 单纯形模板
- 总结一次失败的网站项目
- 2017.9.26 于神之怒加强版 失败总结
- _bzoj1061 [Noi2008]志愿者招募【最小费用最大流】
- 2017.9.4 黑白棋 失败总结
- MySQL数据库建立外键失败的原因总结
- 2017.9.4 斜堆 失败总结
- 2017.3.12 分割矩阵 失败总结
- 我的2014年总结 - 一些失败的面试经历
- 失败的项目总结经验
- 2017.3.13 反素数ant 失败总结
- 2017.10.9 DZY Loves Math VI 失败总结
- 2017.8.15 阿狸的打字机 失败总结
- bzoj 1061 志愿者招募 有上下界费用流做法
- bzoj1061【NOI2008】志愿者招募