关于网络流的复杂度 一般数据范围低于1k就可能考虑网络流
拆点可以限制一条边的流量
一条边连向另一条边 出点---->入点
我的选择是用 dinic
1最大全闭合子图 如果两个东西 (选这个必须选另一个) 那么我们可以 转化为最小割
然后dfs去跑 方案
2限制同时选
3限制同时不选
(最小割真的很妙 也很难 真的很考验思维)
最小割的必经边 首先都是要跑 一遍最小割(最大流等于最小割)
最小割的可行边 跑一遍最小割
最小费用最大流
最大费用最大流
本质是最短路去找一条增广路 但是我们考虑到有负权 (有环的我们另行考虑,下面有解释)
我们选择用spfa 优化
最主要的思想:
ru ++ chu -- >0 有多余 向超级汇点连边 <0 超级源点向这个点连边 做一个供给的效果
经典例题 就是 网络流24题的 餐巾计划问题 我们需要让某条边数流满 而不直接求
如果有负权环的费用流 本质的处理是 把他的负数边留满 那么我们可以向他的 反向边 连 c -inf 的流量
保证它流满
最小点覆盖 最大匹配
最小边覆盖 顶点数-最大匹配数
最大权独立集 顶点数-最大匹配数
最少路径点覆盖 顶点数-最大匹配数
最小路径可重复路径点覆盖 顶点数-传递闭包的最大匹配数
最长反链 =最小可重复路径点覆盖 (比较不常见)
最大团等于补集的 最大全独立集
二分图完备匹配的必经点 可以dfs
二分图完备匹配的必经边 如果满流 正向连边 不在完备匹配的边 反向连边 跑有向图 tarjan
差分建边
我们可以分治处理
然后倍增查询
void build(int l,int r)
{
if(l>=r) return;
int x=pdx[l],y=pdx[l+1];
int cut=Dinic(x,y);
now++;dfs(x);int p=l,q=r;
for(int i=l;i<=r;i++)
if(col[pdx[i]]==now) tdx[p++]=pdx[i];
else tdx[q--]=pdx[i];
for(int i=l;i<=r;i++) pdx[i]=tdx[i];
add_edge(x,y,cut);
add_edge(y,x,cut);
build(l,p-1);build(q+1,r);
}
可结合二分答案 也是比较经典了
会有线段树建图
可以结合树连剖分(代码hard)