题目

       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", n - ans / 2);// 为什么/2  因为二分图两边都遍历了
40     }
41     return 0;
42 }