HDOJ树形DP专题之Godfather

题目链接

这题Balance Act那题差不多,不过这题的数据量更大,时间有点卡,我的O(N)的算法都跑了1100多MS(时限2S)。

View Code
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <vector> 
 4 #define N 50005
 5 #define MAX(a,b) ((a)>(b)?(a):(b))
 6 using namespace std;
 7 vector<int> dep[N];
 8 int u[2*N],v[2*N],first[N],next[2*N];
 9 int n,p[N],d[N],sum[N],w[N],ans[N],cnt,dmax;
10 void dfs(int i,int fa)
11 {
12   int e,j;
13   d[i]=(fa==-1?0:d[fa]+1);
14   dep[d[i]].push_back(i);
15   dmax=MAX(dmax,d[i]);
16   for(e=first[i];e>=0;e=next[e])
17   {
18     j=v[e];
19     if(j!=fa) dfs(j,p[j]=i);
20   }
21 }
22 void dp()
23 {
24   int i,j,k,l;
25   memset(w,0,sizeof(w));
26   for(i=0;i<n;i++)  sum[i]=1;
27   for(i=dmax;i>=0;i--)
28   {
29     l=dep[i].size();
30     for(k=0;k<l;k++)
31     {
32       j=dep[i][k];
33       w[j]=MAX(w[j],n-sum[j]);
34       if(i>0) w[p[j]]=MAX(w[p[j]],sum[j]),sum[p[j]]+=sum[j];
35     }
36   }
37 }
38 int main()
39 {
40   int i,e,a,b,min;
41   while(~scanf("%d",&n))
42   {
43     memset(first,-1,sizeof(first));
44     memset(next,-1,sizeof(next));
45     for(e=0;e<n-1;e++)
46     {
47       scanf("%d%d",&a,&b);
48       a--,b--;
49       u[2*e]=a,v[2*e]=b;
50       next[2*e]=first[u[2*e]];
51       first[u[2*e]]=2*e;
52       u[2*e+1]=b,v[2*e+1]=a;
53       next[2*e+1]=first[u[2*e+1]];
54       first[u[2*e+1]]=2*e+1;
55     }
56     dmax=0;
57     for(i=0;i<n;i++)  dep[i].clear();
58     dfs(0,-1);
59     dp();
60     min=0x7fffffff;
61     cnt=0;
62     for(i=0;i<n;i++)
63     {
64       if(w[i]<min)  min=w[i],cnt=0,ans[cnt++]=i;
65       else if(w[i]==min)  ans[cnt++]=i;
66     }
67     printf("%d",ans[0]+1);
68     for(i=1;i<cnt;i++)  printf(" %d",ans[i]+1);
69     printf("\n");
70   }
71   return 0;
72 }

 

posted @ 2012-04-27 20:04  BeatLJ  阅读(214)  评论(0编辑  收藏  举报