和poj1655那道求树的重心基本上一样的,代码也没多大改动。
#include<cstdio> #include<algorithm> #include<cstring> #include<vector> using namespace std; #define MAXN 100000 int N; vector<int> node[20005]; int num[MAXN]; //num[i]为以i结点为根的树的所有结点数。 int dp[MAXN]; bool vis[MAXN]; //由于为无向图,所以用这个来标记此结点是否计算过。 int dfs(int id) { int n=node[id].size(); vis[id]=1; num[id]=1; for(int i=0;i<n;i++) { if(!vis[node[id][i]]) num[id]+=dfs(node[id][i]); } return num[id]; } void cal(int id) { int n=node[id].size(); int k; vis[id]=1; for(int i=0;i<n;i++) { k=node[id][i]; if(vis[k]) { dp[id]=max(dp[id],N-num[id]); } else { dp[id]=max(dp[id],num[k]); cal(k); } } } int main() { int a,b; while(scanf("%d",&N)!=EOF) { for(int i=1;i<=N;i++) node[i].clear(); memset(dp,0,sizeof(dp)); for(int i=1;i<N;i++) { scanf("%d%d",&a,&b); node[a].push_back(b); node[b].push_back(a); } memset(vis,0,sizeof(vis)); dfs(1); memset(vis,0,sizeof(vis)); cal(1); for(int i=1;i<=N;i++) { if(dp[i]<=N/2) printf("%d ",i); } } return 0; }