http://acm.timus.ru/problem.aspx?space=1&num=1056
求树的圆心
两遍 bfs 找到直径 然后圆心有一个或两个
代码:
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<vector> #include<set> #include<map> #include<string> #include<queue> #include<stack> #include <iomanip> using namespace std; #define LL long long const int INF=0x3f3f3f3f; const int N=10006; int head[N],I; struct node { int j,next; }side[N*2]; int n; int f[N]; vector<int>road; void add(int i,int j) { side[I].j=j; side[I].next=head[i]; head[i]=I++; } int bfs(int s) { int dist[N]; memset(dist,-1,sizeof(dist)); queue<int>qt; qt.push(s); dist[s]=0; int k=s; while(!qt.empty()) { int x=qt.front();qt.pop(); for(int t=head[x];t!=-1;t=side[t].next) { int j=side[t].j; if(dist[j]==-1) { dist[j]=dist[x]+1; f[j]=x; if(dist[j]>dist[k]) k=j; qt.push(j); } } } road.clear(); int tmp=k; while(tmp!=s) { road.push_back(tmp); tmp=f[tmp]; } road.push_back(s); return k; } int main() { //freopen("data.in","r",stdin); while(cin>>n) { memset(head,-1,sizeof(head)); I=0; for(int i=2;i<=n;++i) { int pre; cin>>pre; add(pre,i); add(i,pre); } bfs(bfs(1)); int m=road.size(); if(m&1) cout<<road[m/2]<<endl; else cout<<min(road[m/2],road[m/2]-1)<<" "<<max(road[m/2],road[m/2]-1)<<endl; } return 0; }