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

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 }