求助!最后一个点WA,链式前向星。
查看原帖
求助!最后一个点WA,链式前向星。
672223
szlh_yanlikun楼主2023/8/16 16:58
#include<bits/stdc++.h>
using namespace std;
#define l long long
const l N=5005;
l nxt[4*N],to[4*N],val[4*N],head[4*N],dep[N],cnt=1;
l now[4*N];
l n,m,s,t,inf=1145141919810;
void add(l u,l v,l w)
{
	nxt[++cnt]=head[u];
	head[u]=cnt;
	to[cnt]=v;
	val[cnt]=w;
}
bool bfs(l s,l t)//bfs构建分层图
{
	for(l i=1;i<=n;i++)
		dep[i]=inf;
	queue<l> q;
	dep[s]=0;
	now[s]=head[s];
	q.push(s);
	while(q.size())
	{
		l u=q.front();
		q.pop();
		for(l i=head[u];i;i=nxt[i])
			if(dep[to[i]]==inf&&val[i]>0)
			{
				dep[to[i]]=dep[u]+1;
				q.push(to[i]);
				now[to[i]]=head[to[i]];
				if(to[i]==t)
					return true;
			}
	}
	return false;
}
l dfs(l s,l limit)//limit是整条增广路对最大流的贡献
{
	if(s==t)
		return limit;
	l flow=0,x;//flow表示经过该点的所有流量和(相当于流出的总量)
	for(l i=head[s];i&&limit;i=nxt[i])
	{
		now[s]=i;
		//对于一个节点x,当它在DFS中走到了第i条弧时,
		//前i−1条弧到汇点的流一定已经被流满而没有可行的路线了
		//那么当下一次在访问节点x时,前i-1条弧就不用再枚举了
		//所以我们可以改变枚举的起点,达到优化剪枝的效果
		if(dep[to[i]]==dep[s]+1&&val[i]>0)
		{
			x=dfs(to[i],min(limit,val[i]));//这个不能放在判断语句中,否则会超时
			if(x==0)
				dep[to[i]]=inf;//剪枝,去掉增广完毕的点
			limit-=x;//limit表示该点剩余流量
			flow+=x;
			val[i]-=x;
			val[i^1]+=x;//(奇数异或1相当于-1,偶数异或1相当于+1)
		}
	}
	return flow;
}
int main()
{
	scanf("%lld%lld",&n,&m);
	s=1,t=m;
	memset(head,-1,sizeof(head));
	for(l i=1;i<=n;i++)
	{
		l u,v,w;
		scanf("%lld%lld%lld",&u,&v,&w);
		add(u,v,w);
		add(v,u,0);//反向边权值为0
	}
	l ans=0;
	while(bfs(s,t))
	{
		ans+=dfs(s,inf);//正向的所有流量和=反向的所有流量和
	}
	printf("%lld",ans);
	return 0;
}
2023/8/16 16:58
加载中...