【最小路径可重点覆盖】Vani和Cl2捉迷藏
题意
给出一张有向无环图\(G=(V,E)\)。\(|V|\leq 200,|E|\leq 30000\)。
求出最多的\(k\)个点使得这\(k\)个点任意两个之间都没有路径相连。
思路
链是一个点的集合,这个集合中任意两个元素\(u,v\),要么\(u\)能走到\(v\),要么\(v\)能走到\(u\)。
反链是一个点的集合,这个集合中任意两点谁也不能走到谁。
最长反链是反链中最长的那个。
该题即求最长反链。
Dilworth定理:最长反链长度=最小链覆盖数
故求出最小路径可重点覆盖即可。
代码
#include <cstdio>
#include <cstring>
const int V = 201, E = 30001;
int n, m, tot, ans;
int f[V][V];
int ver[E], next[E], head[V], line[V], v[V];
int find(int x) {
for (int i = 1; i <= n; i++)
if (f[x][i] && !v[i]) {
v[i] = 1;
if (!line[i] || find(line[i])) {
line[i] = x;
return 1;
}
}
return 0;
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1, x, y; i <= m; i++)
scanf("%d %d", &x, &y), f[x][y] = 1;
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
f[i][j] |= f[i][k] && f[k][j];
for (int i = 1; i <= n; i++) {
memset(v, 0, sizeof(v));
ans += find(i);
}
printf("%d", n - ans);
}

浙公网安备 33010602011771号