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 }

 

你可能感兴趣的:(poj)