二分图 1

“全是板子题“——gtm1514
这样用脑子的板子题我头一次见

二分图判定板子

点击查看代码
bool dfs(int now, int fa, int color) {
	col[now] = color;
	for (int i = head[now]; i; i = e[i].nxt) {
		int to = e[i].to;
		if (to == fa) continue;
		if (col[to] == 0 && !(dfs(to, now, 3-color))) {
			return false;
		}
		if (col[to] == color) return false;
	}
	return true;
}
// 主函数中
bool flag = true;
for (int i = 1; i <= n; ++i) {
	if (!col[i]) {
		if (!(dfs(i, 0, 1))) {
			flag = false;
			break;
		}
	}
}
if (flag) cout <<"YES"<<endl;
else cout <<"NO"<<endl;

最大匹配——匈牙利算法

\(G=<V, E>\)是二分图,\(V\)是点集,左部集合为\(V1\),右部集合为\(V2\)\(E\)是边集,\(M⊆E\)
匹配:若\(M\)中任何两条边没有公共点,则称\(M\)\(G\)的一个匹配
最大匹配:具有边数量最多的匹配称为最大匹配
最大权匹配:当图中的边带权的时候,边权和最大的为最大权匹配。
匹配中的边称为匹配边,反之称为非匹配边。
一个点如果属于\(M\)中至多一条边的端点,称为匹配点,反之称为非匹配点。
完美匹配:若\(|V1|=|V2|=|M|\),则称M为完美匹配
交错路:从一个未匹配的点出发,依次经过未匹配边、匹配边、未匹配边....这样的路叫做交错路。
增广路:从一个未匹配的点出发,走交错路,到达了一个未匹配过的点,这条路叫做增广路。

板子:

点击查看代码
struct G{
	struct edge{
		int t;
		int n;
	}p[o*o];
	int m[o*o],cnt,h[o*o];
	void add(int s,int t){
		cnt++;
		p[cnt].t=t;
		p[cnt].n=h[s];
		h[s]=cnt;
	}
	bool v[o*o];
	bool match(int x){
		for(int i=h[x];i;i=p[i].n){
			int y=p[i].t;
			if(!v[y]){
				v[y]=1;
				if(!m[y]||match(m[y])){
					m[y]=x;
					return true;
				}
			}
		}
		return false;
	}
	void work(){
		for(int i=1;i<=n;i++){
			memset(v,0,sizeof(G.v));
			if(match(i)){
				ans++;
			}
		}
	} 
}G;

最小点覆盖:

给一张二分图,求最小点集\(S\),使图中任意一条边都存在端点属于\(S\)
最小点覆盖点数等于最大匹配边数

最大独立集:

大小等于节点数-最大匹配边数边数

posted @ 2022-04-28 15:48  2K22  阅读(52)  评论(0)    收藏  举报