上下界最小流为什么T了?
  • 板块学术版
  • 楼主Kent999
  • 当前回复5
  • 已保存回复5
  • 发布时间2024/11/23 19:16
  • 上次更新2024/11/23 21:36:31
查看原帖
上下界最小流为什么T了?
225484
Kent999楼主2024/11/23 19:16

rt,上下界有源汇最小流板子T成95了,感觉没啥问题

https://loj.ac/p/11

https://loj.ac/s/2207406

#include<bits/stdc++.h>
using namespace std;
#define ll int
const int inf=1e9;
int n,m,S,T;
struct node{
	ll v,w,nx;
}e[750005];
int cnt,hd[51005],cur[51005];
ll d[51005],sum;
void add(int u,int v,ll w){
	cnt++;
	e[cnt]=node{v,w,hd[u]};
	hd[u]=cnt;
}
void add_edge(int u,int v,ll low,ll up){
	add(u,v,up-low);add(v,u,0);
	d[u]-=low;d[v]+=low;
}
int s,t;
int dis[51005];
bool bfs(){
	queue<int> q;q.push(s);
	memset(dis,-1,sizeof(dis));dis[s]=0;
	while(!q.empty()){
		int u=q.front();q.pop();
		cur[u]=hd[u];
		for(int i=hd[u];i;i=e[i].nx){
			int v=e[i].v;
			if(dis[v]!=-1 || e[i].w==0)continue;
			dis[v]=dis[u]+1;q.push(v);
			if(v==t)return 1;
		}
	}
	return 0;
}
ll dfs(int u,ll flow){
	if(u==t)return flow;
	ll delta=flow;
	for(int &i=cur[u];i;i=e[i].nx){
		int v=e[i].v;
		if(dis[v]!=dis[u]+1 || e[i].w==0)continue;
		ll dans=dfs(v,min(delta,e[i].w));
		e[i].w-=dans;e[((i-1)^1)+1].w+=dans;
		delta-=dans;
		if(delta==0)break;
	}
	return flow-delta;
}
ll dinic(){
	ll ans=0;
	while(bfs())ans+=dfs(s,inf);
	return ans;
}
ll ans=0;
int main(){
	scanf("%d%d%d%d",&n,&m,&S,&T);
	for(int i=1;i<=m;i++){
		int u,v;ll low,up;scanf("%d%d%d%d",&u,&v,&low,&up);
		add_edge(u,v,low,up);
	}
	for(int i=1;i<=n;i++)
		if(d[i]<0)add(i,n+1,-d[i]),add(n+1,i,0);
		else if(d[i]>0)add(0,i,d[i]),add(i,0,0),sum+=d[i];
	add_edge(T,S,0,inf);
	s=0;t=n+1;
	if(dinic()!=sum)puts("please go home to sleep"),exit(0);
	ans=e[cnt].w;e[cnt-1].w=e[cnt].w=0;
	s=T;t=S;ans-=dinic();
	printf("%d\n",ans);
    return 0;
}
2024/11/23 19:16
加载中...