POJ 1770 树形DP

题意:

容器中有 n 种原子,现提供 m 种光子,这 n 种原子中能量之差等于提供的 m 种光子之一所具有的能量,就认为这两种原子是处在容器在是危险的,现在要求取走一些原子,使得容器中的原子处在一块是安全的,同时要求剩下的原子的能量和最大。

 

思路:

很明显的树形dp,每两个处于会产生危险的原子连一条无向边,注意建图完了可能是一个森林!

PS:不会有环么?我AC了以后才发现这个问题。。。网上都没提这事,不知道我没完全理解题?

 

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <iostream>
 5 #include <cmath>
 6 #include <map>
 7 
 8 #define N 10000
 9 #define M 100000
10 
11 using namespace std;
12 
13 map<int,int> mp;
14 
15 int head[N],to[M],next[M],a[N],b[N],cnt,num,n,m,tc[N],dp[N][2];
16 bool vis[N];
17 
18 inline void add(int u,int v)
19 {
20     to[cnt]=v; next[cnt]=head[u]; head[u]=cnt++;
21 }
22 
23 void read()
24 {
25     mp.clear();
26     memset(head,-1,sizeof head);cnt=0;
27     num=0;
28     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
29     for(int i=1;i<=m;i++) scanf("%d",&b[i]);
30     for(int i=1;i<=n;i++)
31         for(int j=i+1;j<=n;j++)
32             for(int k=1;k<=m;k++)
33                 if(abs(a[i]-a[j])==b[k])
34                 {
35                     if(mp[a[i]]==0) {mp[a[i]]=++num;tc[num]=a[i];}
36                     if(mp[a[j]]==0) {mp[a[j]]=++num;tc[num]=a[j];}
37                     int ta=mp[a[i]],tb=mp[a[j]]; 
38                     add(ta,tb),add(tb,ta);
39                 }
40 }
41 
42 void find(int u,int fa)
43 {
44     vis[u]=true;
45     for(int i=head[u];~i;i=next[i])
46         if(to[i]!=fa) find(to[i],u);
47         
48     dp[u][1]=tc[u];dp[u][0]=0;
49     for(int i=head[u];~i;i=next[i])
50         if(fa!=to[i])
51         {
52             dp[u][0]+=max(dp[to[i]][1],dp[to[i]][0]);
53             dp[u][1]+=dp[to[i]][0];
54         }
55 }
56 
57 void go()
58 {
59     memset(dp,0x8f,sizeof dp);
60     memset(vis,0,sizeof vis);
61     int ans=0;
62     for(int i=1;i<=num;i++)
63         if(!vis[i])
64         {
65             find(i,-1);
66             ans+=max(dp[i][0],dp[i][1]);
67         }
68     printf("%d\n",ans);
69 }
70 
71 int main()
72 {
73     while(scanf("%d%d",&n,&m),n||m)
74     {
75         read();
76         go();
77     }
78     return 0;
79 }

 

 

 

posted @ 2012-10-04 21:02  proverbs  阅读(327)  评论(0编辑  收藏  举报