您的位置:首页 > 其它

URAL1056(树的直径)

2014-04-18 11:39 274 查看
题目要求找到所有中心点,中心点是距离其最远的点的距离最小的顶点。

我们知道从任何一点出发DFS其最远的点所经过的路径必与树的直径有交点。

若该点不在树的直径上,则不可能是中心点,因为取树直径的中点可以使得距离其最远的点的距离更小。

还有一种情况是树拥有多条直径,细推一下所有直径的中点是会重合的。(若直径包含偶数个点,则有2个点重合;若直径包含奇数个点,则有1个点重合)

因此根据直径的奇偶性输出树的直径的中点即可,可能是一个或者是两个。

#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <stack>
#include <map>
#include <vector>
using namespace std;

int par[10005];
bool vstd[10005];
vector<int> V[10005];
int maxn;
int record;

void dfs(int v,int depth)
{
int i;
bool flag=false;
vstd[v]=true;

for (i=0;i<(int)V[v].size();i++)
{
if (!vstd[V[v][i]])
{
flag=true;
par[V[v][i]]=v;
dfs(V[v][i],depth+1);
}
}
if (!flag && depth>maxn)
{
record=v;
maxn=depth;
}
}

int main()
{
int n;
scanf("%d",&n);
int i;
for (i=2;i<=n;i++)
{
int x;
scanf("%d",&x);
V[i].push_back(x);
V[x].push_back(i);
}
dfs(1,0);
memset(vstd,false,sizeof(vstd));
maxn=0;
dfs(record,0);
if (maxn%2==0)
{
for (i=1;i<=maxn/2;i++)
record=par[record];
printf("%d\n",record);
}
else
{
for (i=1;i<=maxn/2;i++)
record=par[record];
if (record<par[record])
printf("%d %d\n",record,par[record]);
else
printf("%d %d\n",par[record],record);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: