poj 1192

此题亦一眼看出算法,一次AC。

没什么好讲的,就是一个普通的树形动规。

用dp[n][0]表示n号顶点不取时的最大值,dp[n][1]表示n号顶点取时的最大值。

dp[n][0]=max{dp[x][0],dp[x][1]}(x is son of n)

dp[n][1]=max{sigma(x1,x2,…,xk)}(x1,x2,…,xk are k sons of n)

本来能写O(n)的算法,偷懒写了O(n^2)的算法,也能AC

优化:

用邻接链表,O(n)(我没用)

代码:

#include<cstdio>

#include<cstdlib>

using namespace std;

 

int n,x[1001],y[1001],fa[1001],q[2001],dp[1001][2]={0},p[1001];

bool vis[1001]={0};

int max(int x,int y){

         return(x>y)?x:y;

}

void solve(int x){

         dp[x][0]=0;dp[x][1]=p[x];

         for(int i=1;i<n;i++)

                   if(fa[i]==x){

                            solve(i);

                            dp[x][0]=max(dp[x][0],max(dp[i][0],dp[i][1]));

                            dp[x][1]=dp[x][1]+max(0,dp[i][1]);

                   }

         return;

}

int main(){

         scanf("%d",&n);

         for(int i=0;i<n;i++)

                   scanf("%d%d%d",&x[i],&y[i],&p[i]);

         int h=0,t=1;vis[0]=1;

         for(q[0]=0;h<t;h++){

                   for(int i=0;i<n;i++)

                            if(!vis[i] && abs(x[i]-x[q[h]])+abs(y[i]-y[q[h]])==1){

                                     q[t++]=i;

                                     fa[i]=q[h];

                                     vis[i]=1;

                            }

         }

//      for(int i=0;i<n;i++)printf("%d ",fa[i]);printf("\n");

         solve(0);

         printf("%d\n",max(dp[0][0],dp[0][1]));

         return 0;

}

posted @ 2013-07-01 22:19  shanquan2  阅读(288)  评论(0)    收藏  举报