poj 1466(最大独力集)
证明:
最大独立数=未匹配的节点+匹配数/2 (1) (设n=匹配数/2,可以理解为去掉二分图某侧匹配好的n个节点,在另一侧对应的n个节点就没有相匹配的了) 而 未匹配的节点=顶点数-匹配数 (2) 由(1)(2)得: 最大独立数=顶点数-匹配数的一半
1 // File Name: 1466.cpp 2 // Author: Missa 3 // Created Time: 2013/2/11 星期一 20:24:26 4 5 #include<iostream> 6 #include<cstdio> 7 #include<cstring> 8 #include<algorithm> 9 #include<cmath> 10 #include<queue> 11 #include<stack> 12 #include<string> 13 #include<vector> 14 #include<cstdlib> 15 #include<map> 16 using namespace std; 17 #define CL(x,y) memset(x,y,sizeof(x)); 18 19 const int maxn = 5e2+5; 20 int n; 21 bool vis[maxn]; 22 int ma[maxn][maxn]; 23 int link[maxn]; 24 bool dfs(int x) 25 { 26 for(int i=0;i<n;i++) 27 { 28 if(!vis[i] && ma[x][i]) 29 { 30 vis[i]=1; 31 if(link[i]==-1 || dfs(link[i])) 32 { 33 link[i]=x; 34 return true; 35 } 36 } 37 } 38 return false; 39 } 40 int maxmatch() 41 { 42 int c=0; 43 CL(link,-1); 44 for(int i=0;i<n;i++) 45 { 46 CL(vis,0); 47 if(dfs(i)) c++; 48 } 49 return c; 50 } 51 52 int main() 53 { 54 while(~scanf("%d",&n)) 55 { 56 CL(ma,0); 57 for(int i=0;i<n;i++) 58 { 59 int c,x; 60 scanf("%d: (%d)",&c,&c); 61 while(c--) 62 { 63 scanf("%d",&x); 64 ma[i][x]=1; 65 } 66 } 67 printf("%d\n",n-maxmatch()/2); 68 } 69 return 0; 70 }