二分图
By Shui_Dream大神 Orz
听天书。
一张无向图是二分图,当且仅当其无奇环。
比较显然,可以用染色法判定。
将 \(n\) 个点分成两组,最小化
\(bl_i\in\lbrack 0,1\rbrack\) .
二分一个答案 \(c\) ,把大于 \(c\) 的边取出来判定二分图即可。\(O(n\space log\space V)\)
序列 \(a\) ,\(m\) 种操作 \((t_i,u_i,v_i)\) , \(t_i=1\) 则同加同减,\(t_i=2\) 则一加一减,问能否任意操作变为序列 \(b\) .
\(n,m\le 10^5\) .
令 \(a_i\rightarrow a_i-b_i\) .
\((2,a,b),(2,b,c)\) 可得 \((2,a,c)\) ,构成连通块,那么这些连通块内的点可以加减且总权值不变。
\((1,a,b),(2,b,c)\) 得 \((1,a,c)\) ,若两个连通块间有 \(1\) 边,相对于对连通块内的两个点进行 \(1\) 操作。
等下再补。
二分图最大匹配
匈牙利算法:不断找增广路,找到则权值加 \(1\) .
#include<bits/stdc++.h>
#define N 510
using namespace std;
int n,m,e,u,v,ans;
vector<int>s[N];
int vis[N],match[N];
bool dfs(int x){
for(int i=0,y;i<s[x].size();i++)
if(!vis[y=s[x][i]]){
vis[y]=true;
if(!match[y]||dfs(match[y])){
match[y]=x;
return true;
}
}
return false;
}
int main(){
scanf("%d%d%d",&n,&m,&e);
while(e--){
scanf("%d%d",&u,&v);
s[u].push_back(v);
}
for(int i=1;i<=n;i++){
memset(vis,0,sizeof(vis));
ans+=dfs(i);
}
printf("%d\n",ans);
return 0;
}
\(O(nm)\) .
也可以用 \(\text{bfs}\) ,复杂度一致,略困难不记了。
-
二分图的最大独立集点数=总点数-最大匹配数
分别记为 \(U,V,M\) ,显然 \(U\le V-M\) .
其次有 \(U\ge V-2M\) ,不在最大匹配中的点都能进入最大独立集,否则能产生新的匹配。
对于最大匹配的一个匹配边,定能将其一加入点集,所以 \(U\ge V-M\) .
可以得到 \(U=V-M\) .
-
二分图的最小点覆盖=最大匹配数
无向图中,总点数=最大独立集+最小点覆盖。
若 \(V_1\) 为点覆盖,记 \(V_2=V-V_1\) .
若 \(V_2\) 非独立集,那么存在边没有被覆盖。
容易得到性质。
\(n\times n\) 的棋盘上存在障碍物,问最多能放多少马使得他们能不相互攻击。\(n\le 200\) .
这个能变成最大独立集的形式。
等于跑二分图,得用网络流。
\(A,B\) 分别有 \(n,m\) 种模式,初始为 \(0\) .
\(k\) 个任务,在 \(A\) 上执行要将模式切为 \(a_i\) ,否则 \(B\) 切成 \(b_i\) .
任务可以以任意顺序进行,问最小切换次数。
多测,以 \(0\) 结束。
\(n,m\le 100,1\le k\le1000,0\le a_i<n,0\le b_i<m\) .
\(a_i,b_i\) 连边(区分左右部点),能看出来这是一个最小点覆盖问题。
求一个 DAG(有向无环图)的最小路径覆盖。
\(n\le 150,m\le6000\) .
将点 \(i\) 拆成 \(i\) 和 \(n+i\) ,对有向边 \((u,v)\) 连接 \((u,n+v)\) .
补。
给定 \(\lbrack 0,n-1\rbrack\) 的排列 \(T\) ,变换后 \(i\rightarrow T_i\) .
定义 \(dis(x,y)=min(|x-y|,n-|x-y|)\) ,给定所有 \(dis(i,T_i)\) ,问是否存在 \(T\) ,并给出字典序最小者。
补。
补。
二分图最大权匹配
最大匹配的前提下最大化边权总和。
KM算法:为点 \(u\) 设顶标 \(lx_u\space/\space ly_u\) .
可行顶标为 \(lx_u+ly_v\ge W_{u,v}\) 的顶标。
期望在找增广路时,找到 \(lx_u+ly_v=W_{u,v}\) 的期望边,若否则调整定标来降低期望,找到最优的边。
等下补,还没学会。
\(\text{dfs}\space O(n^2m)\) , \(\text{bfs}\space O(n^3)\) .
跑费用流也行。