求最大独立集。
二分图的独立数等于顶点数减去最大匹配数。
由于此题中不明男女,所以把所有人弄成两个集合,故最后要减去最大匹配数的一半。
View Code
1 /* 2 Author:Zhaofa Fang 3 Lang:C++ 4 */ 5 #include <cstdio> 6 #include <cstdlib> 7 #include <iostream> 8 #include <cmath> 9 #include <cstring> 10 #include <algorithm> 11 #include <string> 12 #include <vector> 13 #include <queue> 14 #include <stack> 15 #include <map> 16 #include <set> 17 #define pb push_back 18 using namespace std; 19 20 //========================================== 21 //最大独立点集=顶点数-最大匹配数的一半 22 23 const int maxn=500; 24 bool vist[maxn]; 25 int match[maxn],n; 26 struct Edge 27 { 28 int v,next; 29 }edge[maxn*maxn]; 30 int num,p[maxn]; 31 32 void addedge(int u,int v) 33 { 34 edge[num].v=v; 35 edge[num].next=p[u]; 36 p[u]=num++; 37 } 38 bool dfs(int u) 39 { 40 for(int i=p[u];i;i=edge[i].next) 41 { 42 int v=edge[i].v; 43 if(!vist[v]) 44 { 45 vist[v]=true; 46 if(match[v]==-1 || dfs(match[v])) 47 { 48 match[v]=u; 49 return true; 50 } 51 } 52 } 53 return false; 54 } 55 56 int Match() 57 { 58 int cnt=0; 59 for(int i=0;i<n;i++)match[i]=-1; 60 for(int u=0;u<n;u++) 61 { 62 for(int i=0;i<n;i++)vist[i]=0; 63 if(dfs(u))cnt++; 64 } 65 return cnt; 66 } 67 68 int main() 69 { 70 while(~scanf("%d",&n)) 71 { 72 for(int i=0;i<n;i++)p[i]=0; 73 num=1; 74 for(int i=0;i<n;i++) 75 { 76 int u,m; 77 scanf("%d: (%d)",&u,&m); 78 int v; 79 for(int j=0;j<m;j++) 80 { 81 scanf("%d",&v); 82 addedge(u,v); 83 } 84 } 85 printf("%d\n",n-(Match()>>1)); 86 } 87 return 0; 88 }