BZOJ 2502: 清理雪道 【上下界网络流】

BZOJ题目传送门
洛谷题目传送门

题目分析:

每条边流量下限为1,上限为 ∞ \infty ,建源点汇点向每个点连流量无穷大的边,跑有源汇上下界最小流即可。
对这个的学习可以先看这个dalao博客:有上下界的网络流学习笔记(liu_runda)
推荐看完第一个无源汇之后再配这个的图看一看就比较好理解了有上下界的网络流 学习笔记(Clove_unique)

Code:

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define maxn 105
#define maxm 20005
using namespace std;
const int inf = 0x3f3f3f3f;
int n,m,S,T,ss,tt,tf[maxn];//tf:mintotflow
int fir[maxn],cur[maxn],nxt[maxm],to[maxm],cap[maxm],tot=1;
inline void line(int x,int y,int z){
	nxt[++tot]=fir[x],fir[x]=tot,to[tot]=y,cap[tot]=z;
	nxt[++tot]=fir[y],fir[y]=tot,to[tot]=x,cap[tot]=0;
}
int dis[maxn];
queue<int>q;
bool bfs()
{
	memset(dis,0,sizeof dis);
	dis[T]=1,q.push(T);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=fir[u];i;i=nxt[i]) if(cap[i^1]&&!dis[to[i]]){
			dis[to[i]]=dis[u]+1;
			q.push(to[i]);
		}
	}
	return dis[S];
}
int dfs(int u,int lim)
{
	if(u==T) return lim;
	int need=lim,delta;
	for(int &i=cur[u];i;i=nxt[i]) if(cap[i]&&dis[u]==dis[to[i]]+1){
		delta=dfs(to[i],min(cap[i],need));
		cap[i]-=delta,cap[i^1]+=delta;
		if(!(need-=delta)) break;
	}
	return lim-need;
}
int Dinic(){
	int flow=0;
	while(bfs()) memcpy(cur,fir,sizeof fir),flow+=dfs(S,inf);
	return flow;
}
int main()
{
	scanf("%d",&n);
	for(int i=1,x;i<=n;i++){
		scanf("%d",&m);
		while(m--) scanf("%d",&x),tf[i]--,tf[x]++,line(i,x,inf);
		//下界流量直接加到tf中,上界限制建边容量为上界-下界
	}
	S=0,T=n+1,ss=n+2,tt=n+3;
	for(int i=1;i<=n;i++){
		line(S,i,inf),line(i,T,inf);
		if(tf[i]>0) line(ss,i,tf[i]);
		else if(tf[i]<0) line(i,tt,-tf[i]);
	}
	line(T,S,inf);
	S=ss,T=tt,Dinic();//虚拟源汇补流
	int flow0=cap[tot];//从汇点向源点的反向边流量=源点流出的流量
	cap[tot]=cap[tot-1]=0;//删掉T->S的边
	S=n+1,T=0;//从汇点向源点跑最大流,相减得到最小流
	printf("%d",flow0-Dinic());
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值