萌新刚学OI 1ms,求助网络流
  • 板块灌水区
  • 楼主我很低调
  • 当前回复9
  • 已保存回复9
  • 发布时间2022/8/30 17:06
  • 上次更新2023/10/27 13:03:33
查看原帖
萌新刚学OI 1ms,求助网络流
148552
我很低调楼主2022/8/30 17:06

有源汇有上下界最小流(当前弧优化-->取地址就会超时,赋值秒过)

bdfs后无果

LOJ题面

两份代码不同,求助大佬:

ll dinic(ll u,ll tt,ll flow){
	if(u==tt)return flow;
	ll rst=flow,son;
	for(ll &i=strt[u];i;i=edge[i].nxt){
//	for(ll i=strt[u];i;i=edge[i].nxt){
//		strt[u]=i;
		if(rst==0)break;
		if(deep[edge[i].v]!=deep[u]+1||edge[i].c==0)continue;
		son=dinic(edge[i].v,tt,min(rst,edge[i].c));
		if(son==0)deep[edge[i].v]=0;
		edge[i].c-=son;edge[i^1].c+=son;rst-=son;
	}
	return flow-rst;
}

注释中的代码替换上面的循环后完全无压力通过,上述代码有一个1002ms

评测记录95pts

评测记录AC

全部代码:

#include<cstdio>
#include<cstring>
#define oo 2147483647ll
#define ll long long
using namespace std;
struct node{ll v,c,nxt;}edge[5000006];
ll head[1000006],cnt=1,strt[1000006];
void adge(ll u,ll v,ll c){
	edge[++cnt]=(node){v,c,head[u]};head[u]=cnt;
	edge[++cnt]=(node){u,0,head[v]};head[v]=cnt;
}
ll n,m;
ll S,T;
ll b[4000005],c[4000005];
ll ru[4000005],chu[4000005];
ll u[4000005],v[4000005];
ll Q[1000006],frt,rer;
ll deep[1000004];
bool vis[1000004];
ll min(ll a,ll b){return a<b?a:b;} 
bool bfs(ll ss,ll tt){
	ll u;
	frt=1,rer=0;
	for(ll i=0;i<=n+1;i++)deep[i]=0;
	Q[++rer]=ss;deep[ss]=1;
	while(rer-frt+1){
		u=Q[frt];frt++;
		for(ll i=head[u];i;i=edge[i].nxt){
			if(edge[i].c==0||deep[edge[i].v]!=0)continue;
			deep[edge[i].v]=deep[u]+1;
			Q[++rer]=edge[i].v;
			if(edge[i].v==tt)return true;			
		}
	}
	return false;
}
ll dinic(ll u,ll tt,ll flow){
	if(u==tt)return flow;
	ll rst=flow,son;
	for(ll &i=strt[u];i;i=edge[i].nxt){
//	for(ll i=strt[u];i;i=edge[i].nxt){
//		strt[u]=i;
		if(rst==0)break;
		if(deep[edge[i].v]!=deep[u]+1||edge[i].c==0)continue;
		son=dinic(edge[i].v,tt,min(rst,edge[i].c));
		if(son==0)deep[edge[i].v]=0;
		edge[i].c-=son;edge[i^1].c+=son;rst-=son;
	}
	return flow-rst;
}
int main(){//freopen("a.in","r",stdin);freopen("a.out","w",stdout);
	ll flow;
	ll ans=0;
	ll s,t;
	scanf("%lld%lld%lld%lld",&n,&m,&s,&t);S=0,T=n+1;
	adge(t,s,oo);
	for(ll i=1;i<=m;i++){
		scanf("%lld%lld%lld%lld",&u[i],&v[i],&b[i],&c[i]);
		adge(u[i],v[i],c[i]-b[i]);chu[u[i]]+=b[i];ru[v[i]]+=b[i];
	}
	for(ll i=1;i<=n;i++){
		if(ru[i]-chu[i]>=0)adge(S,i,ru[i]-chu[i]);
		else adge(i,T,chu[i]-ru[i]);
	}
	while(bfs(S,T)){
		for(int i=0;i<=n+1;i++)strt[i]=head[i];
		while(flow=dinic(S,T,oo));
	}
	ans+=edge[3].c;
	edge[2].c=edge[3].c=0;
	for(ll i=head[S];i;i=edge[i].nxt){
		if(edge[i].c!=0)return printf("please go home to sleep\n"),0;
		edge[i].c=edge[i^1].c=0;
	}
	for(ll i=head[T];i;i=edge[i].nxt){
		if(edge[i^1].c!=0)return printf("please go home to sleep\n"),0;
		edge[i].c=edge[i^1].c=0;
	}
	while(bfs(t,s)){
		for(int i=0;i<=n+1;i++)strt[i]=head[i];
		while(flow=dinic(t,s,oo))ans-=flow;
	}
	printf("%lld\n",ans);
	return 0;
}
 

洛谷上的费用流两份代码都是一样的速度,不太清楚为什么,求调谢谢

2022/8/30 17:06
加载中...