题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1068
题目大意:
有n个人,一些人认识另外一些人,选取一个集合,使得集合里的每个人都互相不认识,求该集合中人的最大个数。
解题思路:
这是求最大独立集
最大独立集 = n - 最小覆盖数 = n - 最大匹配
由于这里xy混在一起,可以拆点求最大匹配,最后求得的是真正的最大匹配的两倍
所以答案 = n - maxmatch() / 2
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1000 + 10; 5 const int INF = 1e9; 6 bool Map[maxn][maxn]; 7 int cx[maxn], cy[maxn]; 8 int cntx, cnty; 9 bool vis[maxn]; 10 bool dfs(int u) 11 { 12 for(int v = 0; v < cnty; v++) 13 { 14 if(Map[u][v] && !vis[v]) 15 { 16 vis[v] = 1; 17 if(cy[v] == -1 || dfs(cy[v])) 18 { 19 cx[u] = v; 20 cy[v] = u; 21 return 1; 22 } 23 } 24 } 25 return 0; 26 } 27 int maxmatch() 28 { 29 int ans = 0; 30 memset(cx, -1, sizeof(cx)); 31 memset(cy, -1, sizeof(cy)); 32 for(int i = 0; i < cntx; i++) 33 { 34 if(cx[i] == -1) 35 { 36 memset(vis, 0, sizeof(vis)); 37 ans += dfs(i); 38 } 39 } 40 return ans; 41 } 42 int main() 43 { 44 int n, u, v, t; 45 while(cin >> n) 46 { 47 cntx = cnty = n; 48 memset(Map, 0, sizeof(Map)); 49 while(n--) 50 { 51 scanf("%d: (%d)", &u, &t); 52 while(t--) 53 { 54 scanf("%d", &v); 55 Map[u][v] = 1; 56 } 57 } 58 int ans = maxmatch(); 59 //cout<<ans<<endl; 60 ans = cntx - ans / 2; 61 cout<<ans<<endl; 62 } 63 return 0; 64 }