网络流初步

最大流:从源点到汇点经过若干个点和若干条边,每条边有一个流量限制,求总流量的最大值

1.EK动能算法

交错路:一条源点到汇点的路径满足路径剩余容量>0

思路:每次找出一条交错路,易得这条路径的流量为路径最小剩余流量,将答案加上这条路径的流量并且路径上所有边的容量减掉此流量,就更新完一条交错路

反向建路:对于每一条边,反向建一条容量为0的路,每次更新时反向道路容量加上正向道路所减掉的容量

是因为网络流的流函数f(u,v)=-f(v,u),正向加了多少流量反向就会减去多少流量,反向流量代表着每次更新道路时候可以反悔部分的流量

ll max_flow(){
	queue<int>q;
	ll ans=0;
	while(true){
		while(!q.empty()) q.pop();
		memset(vis,false,sizeof(vis));
		q.push(p_beg);
		memset(flow,0,sizeof(flow));
		flow[p_beg]=inf;
		vis[p_beg]=true;
		while(!q.empty()){
			int x=q.front();
			q.pop();
			for(int i=0;i<tu[x].size();i++){
				int p=tu[x][i].p;
				if(!flow[p]&&tu[x][i].flow&&!vis[p]){
					vis[p]=true;
					flow[p]=min(flow[x],1ll*tu[x][i].flow);
					las[p]=x;
					q.push(p);
				}
			}
			if(flow[p_end]) break;
		}
		if(!flow[p_end]) break;
		int p=p_end;
		while(p!=p_beg){
			tu[p][id[p][las[p]]].flow+=flow[p_end];
			tu[las[p]][id[las[p]][p]].flow-=flow[p_end];
			p=las[p];
		}
		ans+=flow[p_end];
	}
	return ans;
}

2.dinic

EK算法加两个优化

1.分层更新:bfs序在一层的节点一次更新完,将每次更新的节点一个变成多个

2.当前弧优化:不能更新的节点以后一定也不能更新,打上标记

bool get_d(){
	memset(d,0,sizeof(d));
	queue<int>q;
	d[p_beg]=1;
	q.push(p_beg);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=0;i<tu[x].size();i++){
			int p=tu[x][i].p;
			if(v[tu[x][i].vid]&&!d[p]) d[p]=d[x]+1,q.push(p);
		}
		if(d[p_end]) return true;
	}
	return false;
}//寻找bfs序在一层的
int dinic(int x,int flow){
	if(x==p_end) return flow;
	int res=flow;
	for(int i=0;i<tu[x].size();i++){
		int p=tu[x][i].p;
		int vid=tu[x][i].vid;
		if(d[p]!=d[x]+1||!v[vid]) continue;
		int now=dinic(p,min(res,v[vid]));//当前弧优化
		if(!now) d[p]=0;
		res-=now;
		v[vid]-=now,v[vid^1]+=now;
		if(!res) break;
	}
	return flow-res;
}

3.二分图最大匹配的dinic做法

将二分图的左部连向右部的容量设为1,源点连所有左部,右部连汇点,最大流就是最大匹配

因为每条边最多贡献1的权值,最大流就是经过最多的匹配边

时间是n根号m的,主要是空间从n方变道了m,而且dinic跑不满,可以处理点数10w~50w的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值