1 /*
2 Author: Leo.W
3 Descriptipn: 給定一個樹形的地圖,用最少的樹節點使得能夠控制【即所有結點都能一個被占據的結點相連】全樹。
4 How to Do: dp[i][0]=sum{dp[son[i][j]][1]};
5 dp[i][1]=sum{min(dp[son[i][j]][0],dp[son[i][j]][1])};
6 建立結構體,對輸入的信息,記錄子樹的個數及序號,初始是根節點
7 */
8 #include <iostream>
9 using namespace std;
10 #define MAXSIZE 1501
11 int dp[MAXSIZE][2];//對于每一個結點的選擇,放或不放,兩種
12 struct node{
13 int num[MAXSIZE];
14 int lenth;
15 bool isAnc;
16 };
17 node nd[MAXSIZE];
18 inline int mins(int a,int b){
19 return a<b?a:b;
20 }
21 int dfs(int no,int alter){//序號及二選一的選擇
22 if(dp[no][alter]!=INT_MIN)
23 return dp[no][alter];
24 int i,temp=nd[no].lenth;
25 int sum=0;
26 sum+=alter;
27 for(i=0;i<temp;i++){
28 int son=nd[no].num[i];
29 if(alter)
30 sum+=mins(dfs(son,0),dfs(son,1));
31 else
32 sum+=dfs(son,1);
33 }
34 return dp[no][alter]=sum;
35 }
36 int main(){
37 //freopen("in.txt","r",stdin);
38 int n;
39 while(scanf("%d",&n)!=EOF){
40 int i,j;
41 for(i=0;i<n;i++){
42 dp[i][0]=dp[i][1]=INT_MIN;
43 nd[i].isAnc=true;
44 }
45 for(i=0;i<n;i++){
46 int nodeNo,nodeNum;
47 scanf("%d:(%d)",&nodeNo,&nodeNum);
48 nd[nodeNo].lenth=nodeNum;
49 for(j=0;j<nodeNum;j++){
50 int temp;
51 scanf("%d",&temp);
52 nd[nodeNo].num[j]=temp;
53 nd[temp].isAnc=false;
54 }
55 }
56 for(i=0;i<n;i++)
57 if(nd[i].isAnc)
58 break;
59 int ans=mins(dfs(i,0),dfs(i,1));
60 printf("%d\n",ans);
61 }
62 return 0;
63 }
posted on 2012-03-04 10:29
Leo.W 閱讀(291)
評論(0) 編輯 收藏 引用