You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
1.6 KiB

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 5;
/*
测试用例:
2
4
3
3 4
1 3
2 3
3
3
1 3
1 2
2 3
答案:
2
1
*/
int match[N];
int st[N], g[N][N];
int n, m;
int dfs(int x) {
for (int i = 1; i <= n; i++) {
if (g[x][i] && !st[i]) {
st[i] = 1;
int t = match[i];
if (t == -1 || dfs(t)) {
match[i] = x;
return 1;
}
}
}
return 0;
}
int main() {
int T;
cin >> T; // T组测试数据
while (T--) {
cin >> n >> m; // n个节点,m条边
// 多组测试数据
memset(match, -1, sizeof match);
memset(g, 0, sizeof g);
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
g[a][b] = 1; // a->b,有向图
}
// 如果a->b,b->c,则 a->c,题意中说如果存在传递关系,需要我们建立关系清晰的边,也就是,
// 用 floyd,在O(N^3)的复杂度下完善点点之间的边关系
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
g[i][j] |= g[i][k] & g[k][j];
// 新图建成,开始跑匈牙利算法,求二分图的最大匹配
int cnt = 0;
for (int i = 1; i <= n; i++) {
memset(st, 0, sizeof st);
if (dfs(i)) cnt++;
}
// 二分图的最小点覆盖 = n- 二分图的最大匹配
printf("%d\n", n - cnt);
}
return 0;
}