Cansult's blog

即使愿望永远无法实现
我也不愿就这样放手

0%

水题笔记 [CTSC2008]祭祀river [二分图, floyd传递闭包]

天好冷啊

我要妹子

题目

dbzoj

题解

luogu上的还要输出方案, 感觉很蛋疼, 不想做

题目要求我们选一个最大点集, 点之间不能互相到达.

等价于floyd传递闭包后, 选出一个最大点集, 点之间没有边相连, 即求最大独立集

这里讲过做法了

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define MAXM (50000)
#define MAXN (100)
#define rev(i) ((((i) - 1) ^ 1) + 1)
using namespace std;
bool edg[MAXN + 5][MAXN + 5], vis[MAXN + 5];
int link[MAXN + 5], n, m, ans;
bool find(int now) {
for (int i = 1; i <= n; i++)
if (!vis[i] && edg[now][i]) {
vis[i] = true;
if (!link[i] || find(link[i])) {
link[i] = now;
return true;
}
}
return false;
}
void floyd() {
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
edg[i][j] = edg[i][j] || (edg[i][k] && edg[k][j]);
}
int main() {
memset(edg, false, sizeof(edg));
scanf("%d%d", &n, &m);
for (int i = 1, xi, yi; i <= m; i++)
scanf("%d%d", &xi, &yi), edg[xi][yi] = true;
floyd();
for (int i = 1; i <= n; i++) {
memset(vis, false, sizeof(vis));
if (find(i)) ++ans;
}
printf("%d", n - ans);
}

By Cansult