最小点覆盖 最大独立集
最小点覆盖
在二分图中,找出一个最小的点集,使之覆盖所有的边,这个问题被称为二分图的最小点覆盖。
König定理:
二分图最小点覆盖包含的点数等于这个二分图的最大匹配数。
证明:
1.求出二分图的最大匹配,定义:匹配边为包含在最大匹配里的边,匹配点为与匹配边相连的点。
2.从二分图右部的非匹配点开始,按照:非匹配边->匹配边->非匹配边......(交错路)依次将遍历到的结点打上标记。
3.选取左部标记点和右部未标记点即可构成最小点覆盖。
证明懒得写了
二分图最小点覆盖模型特点(“2要素”):每个边有两个端点,两个端点任选其一即可。
题目:POJ 2226
题解:
显而易见:木板越长越好。
对于一个泥地,要么被横着的木板挡住,要么被竖着的木板挡住。先预处理挡住每个泥地木板编号,将横着的木板作为右部结点,竖着的作为左部端点,连边求出最小点覆盖即为答案。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 2505;
const int M = 5000;
int n, m, map[N][N], tot = 0, match[M], tot1 = 0;
int head[N], nextt[M << 1], to[M << 1], cnt = 0;
void add(int x, int y) {
nextt[++cnt] = head[x];
to[cnt] = y; head[x] = cnt;
}
struct node {
int len, row;
} e[N][N];
bool vis[M];
bool dfs(int x) {
for(int i = head[x]; i; i = nextt[i]) {
int y = to[i];
if(vis[y]) continue;
vis[y] = true;
if(!match[y] or dfs(match[y])) {
match[y] = x; return true;
}
}
return false;
}
int main() {
// freopen("data.in", "r", stdin);
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
char s; cin >> s;
if(s == '.') map[i][j] = -1;
}
}
tot = 1;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m;) {
if(map[i][j] == -1) {
tot++;
while(map[i][j] == -1 && j <= m) j++;
} else {
while(map[i][j] != -1 && j <= m) {
e[i][j].len = tot; j++;
}
if(j > m) tot++;
}
}
}
tot1 = 1;
for(int j = 1; j <= m; j++) {
for(int i = 1; i <= n;) {
if(map[i][j] == -1) {
tot1++;
while(map[i][j] == -1 && i <= n) i++;
} else {
while(map[i][j] != -1 && i <= n) {
e[i][j].row = tot1; i++;
}
if(i > n) tot1++;
}
}
}
int ans = 0;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(e[i])
add(e[i][j].row, e[i][j].len);
}
}
for(int i = 1; i <= tot1; i++) {
memset(vis, 0, sizeof(vis));
if(dfs(i)) ans++;
}
printf("%d", ans);
return 0;
}
最大独立集
在二分图中,找出最大的点集,使其中任意两个点都没有边直接相连,这个点集就是最大独立集
最大独立集 = 点数 - 最大匹配
证明:
显然。
选取最多的点构成独立集 <==> 用最少的点覆盖边,总点数去掉最小点覆盖后剩下的点之间没有边直接相连
证毕。
题目:P3355 骑士共存问题
题解:对棋盘进行黑白染色,分成两部分作为左右部结点,能互相攻击到的格子之间连边(观察可知,一种颜色的格子无法攻击和它颜色相同的格子,所以连完边后构成一张二分图)求出最大独立集即为答案。