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 }

 

你可能感兴趣的:(Go)