关于价值为小数的费用流死循环求助
查看原帖
关于价值为小数的费用流死循环求助
299810
issue_is_fw楼主2020/9/24 20:32

RTRT这是小数价值的费用流

我把松弛44行的epseps设置为1e61e-6死循环

但是赋值1e71e-7反而跑的飞快!!!

这似乎和我的认知相反??

随着epseps的减小不是更容易入队么??为什么反而快.....

#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);
}
2020/9/24 20:32
加载中...