1 问题转化: 求二分图最小点覆盖(覆盖所有的边)
2 问题的解决: 二分图最小点覆盖==其最大匹配数
3 证明: 链接
1 =#include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1001; 4 vector < vector <int> > g(N); 5 int match [N]; 6 bool visit[N]; 7 int n; 8 bool dfs (int x) { 9 for (int i=0;i<g[x].size();i++) { 10 int t=g[x][i]; 11 if (!visit[t]) { 12 visit[t]=1; 13 if (match[t]<0||dfs(match[t])) { 14 match[t]=x; 15 return 1; 16 } 17 } 18 } 19 return 0; 20 } 21 int main () 22 { 23 while (~scanf ("%d", &n)) { 24 for (int i=0;i<n;i++) g[i].clear(); 25 memset (match,-1,sizeof(match)); 26 for (int i = 1; i <= n; i++) { 27 int id, num; 28 scanf ("%d: (%d)", &id, &num); 29 for (int j = 0; j < num;j++) { 30 int u; scanf ("%d", &u); 31 g[id].push_back(u); 32 } 33 } 34 int ans = 0; 35 for (int i = 0; i < n; i++) { 36 memset (visit, 0, sizeof(visit)); 37 if (dfs(i)) ans++; 38 } 39 printf("%d ", n - ans / 2);// 为什么/2 因为二分图两边都遍历了 40 } 41 return 0; 42 }