poj 1192-最优连通子集解题报告

简单的树形dp,dp[i][0]表示不选i节点以i为根的子树获得的最大值。既然根节点不选,那么子节点只能选一个,否则无法保证连通。根节点若选的话则把所有状态值为正的节点都选了既为最优值

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #define N 1005
 4 int max(int a,int b)
 5 {
 6     return a>b?a:b;
 7 }
 8 int dir[4][2]={0,1,0,-1,1,0,-1,0};
 9 int head[N],t;
10 struct edge
11 {
12     int v,next;
13 };
14 edge e[2*N];
15 int val[N];
16 struct point
17 {
18     int x,y;
19 };
20 point p[N];
21 void add(int u,int v)
22 {
23     e[t].v=v;
24     e[t].next=head[u];
25     head[u]=t++;
26 }
27 int dp[N][2];
28 bool used[N];
29 void init()
30 {
31     memset(used,0,sizeof(used));
32     memset(head,-1,sizeof(head));
33     t=0;
34 }
35 void dfs(int u)
36 {
37     used[u]=true;
38     int i,v;
39     dp[u][0]=0;
40     dp[u][1]=val[u];
41     for(i=head[u];i>=0;i=e[i].next)
42     {
43         v=e[i].v;
44         if(!used[v])
45         {
46             dfs(v);
47             dp[u][0]=max(dp[u][0],max(dp[v][0],dp[v][1]));
48             if(dp[v][1]>0)
49             dp[u][1]+=dp[v][1];
50         }
51     }
52 }
53 int main()
54 {
55     int n;
56     int i,j,k;
57     scanf("%d",&n);
58     init();
59     for(i=1;i<=n;i++)
60     {
61         scanf("%d%d%d",&p[i].x,&p[i].y,&val[i]);
62         for(j=1;j<i;j++)
63         {
64             for(k=0;k<4;k++)
65             {
66                 if(p[j].x==p[i].x+dir[k][0]&&p[j].y==p[i].y+dir[k][1])
67                 {
68                     add(i,j);
69                     add(j,i);
70                     break;
71                 }
72             }
73         }
74     }
75     dfs(1);
76     printf("%d\n",max(dp[1][0],dp[1][1]));
77     return 0;
78 }
posted @ 2012-06-07 00:06  zhenhai  阅读(292)  评论(2编辑  收藏  举报