RT这是小数价值的费用流
我把松弛44行的eps设置为1e−6死循环
但是赋值1e−7反而跑的飞快!!!
这似乎和我的认知相反??
随着eps的减小不是更容易入队么??为什么反而快.....
#include <bits/stdc++.h>
using namespace std;
const double eps=1e-8;
const int maxn=2e5+10;
const int inf=1e9;
int n,m,s,t,a,b;
double maxflow,mincost;
double dis[maxn];
int head[maxn<<1],cnt=1,incf[maxn],pre[maxn],vis[maxn];
struct edge{
int to,nxt,flow; double w;//分别代表
}d[maxn<<1];
void add(int u,int v,int flow,double w)//最大流量,单位费用
{
d[++cnt]=(edge){v,head[u],flow,w},head[u]=cnt;
d[++cnt]=(edge){u,head[v],0,-w},head[v]=cnt;
}
bool spfa()
{
queue<int>q;
for(int i=0;i<=t;i++) dis[i]=inf,vis[i]=0;
q.push(s);
dis[s]=0,vis[s]=1;
incf[s] = inf;//初始流量无限大
while( !q.empty() )
{
int u=q.front(); q.pop();
vis[u]=0;//出队
for(int i=head[u];i;i=d[i].nxt)
{
if( !d[i].flow ) continue;//无流量了
int v=d[i].to;
if( dis[v]>dis[u]+d[i].w+eps )
{
dis[v]=dis[u]+d[i].w;
incf[v] = min(incf[u],d[i].flow);//更新当前流量
pre[v]=i;//记录从哪条边过来的
if( !vis[v] ) vis[v]=1,q.push(v);
}
}
}
if( dis[t]==inf ) return 0;
return 1;
}
void dinic()
{
while( spfa() )
{
int x=t;//倒回去找路径
maxflow+=incf[t];
mincost+=dis[t]*incf[t];
int i;
while(x != s)
{
i=pre[x];
d[i].flow-=incf[t];//减去流量
d[i^1].flow+=incf[t];//加上流量
x = d[i^1].to;//因为是倒回去,所以利用反向边倒回去
}
}
}
double p[maxn],u[maxn];
int main()
{
cin >> n >> a >> b;
s=0,t=n+3;
add(s,n+1,a,0);
add(s,n+2,b,0);
for(int i=1;i<=n;i++)
{
scanf("%lf",&p[i] );
add(n+1,i,1,-p[i]);
}
for(int i=1;i<=n;i++)
{
scanf("%lf",&u[i] );
add(n+2,i,1,-u[i]);
add(i,t,1,0);
add(i,t,1,u[i]*p[i]);
}
dinic();
printf("%.6lf",-mincost);
}