树的中心
题目大意:给你一棵树,求其中心。
当然,这只是大意,题目中有N多坑点等你发现哟!
思路的话就是搜索两遍求出其直径,在第二次搜索的时候记录路径,然后就可以取其中点啦!
网上大神用的都是DFS,于是本蒟蒻就义无反顾地用了BFS ( • ̀ω•́ )✧
经本人实测发现的坑点如下:
1.坐标只是给你连边用的,之后跑搜索的时候权值都为1。
2.因为题目上说是逐步占领的,这就意味着对于第i个点,只需考虑前i-1个点到它的距离即可(就是因为这个地方我RE了)。
3.若有两个中点的话先输编号小的那个。
就酱。
贴上代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 1000
using namespace std;
struct edge{
int next;
int to;
};
int n,m;
int a[MAXN+5][5],num[MAXN+5],h[MAXN+5];
int w[MAXN+5],pre[MAXN+5],b[MAXN+5],v[MAXN+5];
double dis[MAXN+5];
edge ed[2*MAXN+5];
bool f[MAXN+5];
double calc(int x1,int y1,int z1,int x2,int y2,int z2){
double x=x2-x1;
double y=y2-y1;
double z=z2-z1;
return sqrt(x*x+y*y+z*z);
}
void read(int x,int y){
ed[++m].next=h[x];
ed[m].to=y;
h[x]=m;
}
void bfs1(){
memset(w,0,sizeof(w));
memset(f,false,sizeof(f));
b[1]=1;
int l=0,r=1;
while (l<r){
int x=b[++l];
f[x]=true;
for (int i=h[x];i;i=ed[i].next)
if (!f[ed[i].to]){
w[ed[i].to]=w[x]+1;
b[++r]=ed[i].to;
}
}
}
int bfs(int now){
memset(f,false,sizeof(f));
memset(v,0,sizeof(v));
memset(pre,0,sizeof(pre));
b[1]=now;
int l=0,r=1;
while (l<r){
int x=b[++l];
f[x]=true;
for (int i=h[x];i;i=ed[i].next)
if (!f[ed[i].to]){
v[ed[i].to]=v[x]+1;
b[++r]=ed[i].to;
pre[ed[i].to]=x;
}
}
int ans=0,sum=0;
for (int i=1;i<=n;i++)
if (sum<v[i]){
sum=v[i];
ans=i;
}
return ans;
}
int main(){
while(~scanf("%d",&n)&&n){
memset(a,0,sizeof(a));
memset(dis,127,sizeof(dis));
for (int i=1;i<=n;i++)
scanf("%d%d%d%d",&a[i][1],&a[i][2],&a[i][3],&a[i][4]);
for (int i=1;i<=n;i++)
for (int j=1;j<i;j++)
if (calc(a[i][2],a[i][3],a[i][4],a[j][2],a[j][3],a[j][4])<dis[i]){
dis[i]=calc(a[i][2],a[i][3],a[i][4],a[j][2],a[j][3],a[j][4]);
num[i]=j;
}
m=0;
memset(h,0,sizeof(h));
for (int i=1;i<=n;i++){
read(i,num[i]);
read(num[i],i);
}
bfs1();
int x,sum=0;
for (int i=1;i<=n;i++)
if (w[i]>sum){
sum=w[i];
x=i;
}
int y=bfs(x);
if (v[y]%2==0){
int t=1,now=y;
while(t!=v[y]/2+1){
t++;
now=pre[now];
}
printf("%d\n",now);
}
else{
int t=1,now=y;
while (t!=v[y]/2+1){
t++;
now=pre[now];
}
int k=a[now][1];
now=a[pre[now]][1];
if (k>now) swap(k,now);
printf("%d %d\n",k,now);
}
}
return 0;
}