_xiaobai_

导航

zoj1134 Strategic Game(DP/图论)

/*
 简单的树形DP:利用搜索正向求解。
      0的孩子必须是1,1的孩子任意,取最小的。
*/

View Code
 1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #define min(x,y) ((x)<(y)?(x):(y))
6
7 typedef struct node
8 {
9 int Count;
10 int Value;
11 int Next[ 10 ];
12 }node;
13 node Node[ 1510 ];
14 int Root;
15
16 typedef struct answ
17 {
18 int sum0;
19 int sum1;
20 }Answ;
21 Answ Save;
22
23 /*
24 void trival( node * Root )
25 {
26 if ( Root ) {
27 printf("%d",Root->Value);
28 printf("(");
29 for ( int i = 0 ; i < Root->Count ; ++ i )
30 trival( Root->Next[ i ] );
31 printf(")");
32 }
33 }
34 */
35
36 Answ dp( int Root )
37 {
38 Answ an;
39 an.sum0 = 0;
40 an.sum1 = 1;
41 if ( Node[ Root ].Count ) {
42 for ( int i = 0 ; i < Node[ Root ].Count ; ++ i ) {
43 Save = dp( Node[ Root ].Next[ i ] );
44 an.sum0 += Save.sum1;
45 an.sum1 += min( Save.sum0, Save.sum1 );
46 }
47 }
48 return an;
49 }
50
51 int main()
52 {
53 int n,a,m,b;
54 while ( scanf("%d",&n) != EOF ) {
55 Root = -1;
56 memset( Node, 0, sizeof( Node ) );
57 for ( int i = 0 ; i < n ; ++ i ) {
58 scanf("%d:(%d)",&a,&m);
59 if ( Root == -1 ) Root = a;
60 Node[ a ].Count = m;
61 Node[ a ].Value = a;
62 for ( int j = 0 ; j < m ; ++ j ) {
63 scanf("%d",&b);
64 Node[ a ].Next[ j ] = b;
65 }
66 }
67 Answ answer = dp( Root );
68 printf("%d\n",min( answer.sum0, answer.sum1 ));
69 }
70 return 0;
71 }

/*

  图论解法:最小顶点覆盖 = N - 最大独立点 = 最大匹配

*/

View Code
 1 #include <stdio.h>
2 #include <stdlib.h>
3
4 typedef struct node
5 {
6 int Point;
7 node* Next;
8 }node;
9 node Node[ 3001 ];
10 node *Head[ 1501 ];
11 bool Used[ 1501 ];
12 int Result[ 1501 ];
13
14 bool find( int a, int n )
15 {
16 for ( node *P = Head[ a ] ; P ; P = P->Next )
17 if ( !Used[ P->Point ] ) {
18 Used[ P->Point ] = true;
19 if ( Result[ P->Point ] == -1 || find( Result[ P->Point ] , n ) ) {
20 Result[ P->Point ] = a;
21 return true;
22 }
23 }
24 return false;
25 }
26
27 int argument( int n )
28 {
29 for ( int i = 0 ; i < n ; ++ i )
30 Result[ i ] = -1;
31 int Count = 0;
32 for ( int i = 0 ; i < n ; ++ i ) {
33 for ( int j = 0 ; j < n ; ++ j )
34 Used[ j ] = false;
35 if ( find( i, n ) )
36 ++ Count;
37 }
38 return Count;
39 }
40
41 int main()
42 {
43 int n,a,m,b;
44 while ( scanf("%d",&n) != EOF ) {
45 for ( int i = 0 ; i < n ; ++ i )
46 Head[ i ] = NULL;
47 int Count = 0;
48 for ( int i = 0 ; i < n ; ++ i ) {
49 scanf("%d:(%d)",&a,&m);
50 for ( int j = 0 ; j < m ; ++ j ) {
51 scanf("%d",&b);
52 Node[ Count ].Next = Head[ a ];
53 Node[ Count ].Point = b;
54 Head[ a ] = &Node[ Count ++ ];
55 Node[ Count ].Next = Head[ b ];
56 Node[ Count ].Point = a;
57 Head[ b ] = &Node[ Count ++ ];
58 }
59 }
60 printf("%d\n",argument( n )/2);
61 }
62 return 0;
63 }

posted on 2011-08-18 01:55  _xiaobai_  阅读(211)  评论(0编辑  收藏  举报