题目来源:http://acm.pku.edu.cn/JudgeOnline/problem?id=1466
这是一道典型的二分匹配的题目,并且非常简单,使用模板即可AC。
题目大意:在N个点的图G中选出m个点,使这m个点两两之间没有边.求m最大值.
如果图G满足二分图条件,则可以用二分图匹配来做.最大独立集点数 = N - 最大匹配数。
最大独立数=未匹配的节点+匹配数/2 (1)(设n=匹配数/2,可以理解为去掉二分图某侧匹配好的n个节点,在另一侧对应的n个节点就没有相匹配的了)
未匹配的节点=顶点数-匹配数 (2)
由(1)(2)得: 最大独立数=顶点数-匹配数的一半
下面是我的代码:
1 #include < stdio.h >
2 #include < string .h >
3 #define Maxn 505
4
5 int g[Maxn][Maxn], link[Maxn];
6 bool used[Maxn];
7 int n, nx, ny, match;
8
9 bool find( int x)
10 {
11 for ( int i = 1 ; i <= g[x][ 0 ]; i ++ )
12 {
13 int k = g[x][i];
14 if ( ! used[k])
15 {
16 used[k] = true ;
17 if (link[k] ==- 1 || find(link[k]))
18 {
19 link[k] = x;
20 return true ;
21 }
22 }
23 }
24 return false ;
25 }
26
27 void Hungary()
28 {
29 memset(link, - 1 , sizeof (link));
30 for ( int i = 0 ; i < nx; i ++ )
31 {
32 memset(used, false , sizeof (used));
33 if (find(i))
34 match ++ ;
35 }
36 }
37
38 int main()
39 {
40 int n;
41 while (scanf( " %d " , & n) != EOF)
42 {
43 nx = n, ny = n;
44 for ( int i = 0 ; i < nx; i ++ )
45 {
46 int x;
47 char c, cc, str[ 10 ];
48 scanf( " %d%c " , & x, & c);
49 g[x][ 0 ] = 0 ;
50 scanf( " %c%d%c " , & c, & g[x][ 0 ], & cc);
51 for ( int j = 1 ; j <= g[x][ 0 ]; j ++ )
52 scanf( " %d " , & g[x][j]);
53 }
54
55 match = 0 ;
56 Hungary();
57 printf( " %d\n " ,nx - match / 2 );
58 }
59 return 0 ;
60 }
61
62