专栏文章

基础网络流做题方法简单归纳与整理

算法·理论参与者 3已保存评论 6

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
6 条
当前快照
1 份
快照标识符
@miqfvpyu
此快照首次捕获于
2025/12/04 04:08
3 个月前
此快照最后确认于
2025/12/04 04:08
3 个月前
查看原文
做网络流的一个重要的思路就是不管三七二十一先建模,然后把一些决策丢给网络流来思考。
推荐题单:【小峰の题单】网络流经典题目
推荐模板总结:【实时更新】提高-省选级模板汇总
粘一点代码凑长度
最大流最小割:
CPP
bool bfs()
{
	for(int i=1;i<=n;i++)dis[i]=inf;//注意初始化是否完全,这里的 n 可以写为 t
	while(q.size())q.pop();
	q.push(s),dis[s]=0,now[s]=head[s];
	int u;
	while(q.size())
	{
		u=q.front(),q.pop();
		for(int i=head[u];i;i=e[i].nxt)
		{
			int v=e[i].to;
			if(e[i].val&&dis[v]==inf)
			{
				dis[v]=dis[u]+1,now[v]=head[v],q.push(v);
				if(v==t)return 1;
			}
		}
	}
	return 0;
}
int dfs(int u,int flow)
{
	if(u==t)return flow;
	int t,res=0;
	for(int i=now[u];i&&flow;i=e[i].nxt)
	{
		int v=e[i].to;
		now[u]=i;//当前弧优化
		if(e[i].val&&dis[v]==dis[u]+1)
		{
			t=dfs(v,min(e[i].val,flow));
			if(!t)dis[v]=inf;
			e[i].val-=t,e[i^1].val+=t,res+=t,flow-=t;
		}
	}
	return res;
}//真的 dinic
费用流:
CPP
bool spfa()
{
	for(int i=1;i<=n;i++)dis[i]=inf,vis[i]=0;
	memcpy(now,head,sizeof head);
	while(q.size())q.pop();
	q.push(s),dis[s]=0,vis[s]=1;
	int u;
	while(q.size())
	{
		u=q.front(),q.pop(),vis[u]=0;
		for(int i=head[u];i;i=e[i].nxt)
		{
			int v=e[i].to;
			if(e[i].val&&dis[v]>dis[u]+e[i].cost)
			{
				dis[v]=dis[u]+e[i].cost;
				if(!vis[v])q.push(v),vis[v]=1;
			}
		}
	}
	return dis[t]!=inf;
}//spfa 建分层图
int dfs(int u,int flow)
{
	if(u==t)return flow;
	vis[u]=1;
	int x,res=0;
	for(int &i=now[u];i&&res<flow;i=e[i].nxt)
	{
		int v=e[i].to;
		if(!vis[v]&&e[i].val&&dis[v]==dis[u]+e[i].cost)
		{
			x=dfs(v,min(e[i].val,flow-res));
			if(x)e[i].val-=x,e[i^1].val+=x,res+=x,cst+=x*e[i].cost;
		}
	}
	vis[u]=0;
	return res;
}//这里用的是正规的 dinic,模板题题解几乎全是 EK

一,最大流建模,考虑流量意义

  1. 主主树 每个人拆成打人的和被打的,直接通过矛盾关系建图即可
  2. 最小路径覆盖问题 每个点看做一条链,拆成起点 xx 和终点 xx,流量的意义为合并链,最后再残余流量上建并查集输出方案
  3. 教辅的组成 匹配类问题,根据匹配关系连边

二,最小割建模,考虑如何选边

  1. [ZJOI2009] 狼和羊的故事 最小割只割 sts \to t,所以不用考虑反向边的影响
  2. 方格取数问题 四联通矛盾考虑通过黑白二分图染色来表达
  3. [ARC176E] Max Vector 取值可以转化为割边,常规做法(dp,贪心)不好做考虑抽象思维上升到图论

三,费用流建模,设计流量表达合法性,费用表达最优解

  1. 负载平衡问题 搬一次的费用为 11 表示搬运次数
  2. 餐巾计划问题 逆向思维,如果使用后可以回收,考虑在保证存在的情况下把使用后的物品当原料。
  3. [CQOI2012] 交换棋子 流量表达能否达到目标状态,费用表达交换次数,黑白可以只考虑一种

四,概括性做题方法总结

  1. 拆点,设计一个为起始点一个为终止点,通过设计中间的边来解决问题
  2. 寻找矛盾/关联,通过这样的关系建边
  3. 逆向思维,转化题意。这一点在其他算法中也颇为常见

评论

6 条评论,欢迎与作者交流。

正在加载评论...