代码改变世界

1021 Deepest Root

2018-08-21 17:02  legend聪  阅读(188)  评论(0编辑  收藏  举报

这道题的关键在于如何求两个最远的结点,二叉树比较容易一直DFS就能找到,但是普通树就比较麻烦。要先找到一端,再去找另外一端,两端的并集就是答案。因为结点都是对称的,所以两端都是答案。还要注意去重,12 13这种就会重复。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 10010;
vector<int>pre[maxn];
int n;
bool vis[maxn];
vector<int>ans;
void DFS(int s)
{
    int i;
    vis[s] = true;
    for (i =0;i<pre[s].size(); i++)
    {
        if (vis[pre[s][i]] == false)
        {
            DFS(pre[s][i]);
        }
    }
    return;
}
vector<int>temp;
int maxh = 0;
void find(int s,int height)//寻找以s为根距离s最远的结点,height为s距离该节点的距离.
{
    if (vis[s] == true)
        return;
    vis[s] = true;
    if (height > maxh)
    {
        temp.clear();
        temp.push_back(s);
        maxh = height;
    }
    else if (height == maxh)
    {
        temp.push_back(s);
    }
    int i;
    for (i = 0; i < pre[s].size(); i++)
    {
        find(pre[s][i], height + 1);
    }
}
int main()
{
    scanf("%d", &n);
    int i, j;
    for (i = 1; i <= n-1; i++)
    {
        int st, ed;
        scanf("%d %d", &st,&ed);
        pre[st].push_back(ed);
        pre[ed].push_back(st);
    }
    memset(vis, false, sizeof(vis));
    int sum = 0;
    for (i = 1; i <= n; i++)
    {
        if (vis[i] == false)
        {
            sum++;
            DFS(i);
        }
    }
    if (sum >=2)
    {
        printf("Error: %d components\n", sum);
    }
    else if (n == 1)
    {
        printf("%d\n", 1);
    }
    else
    {
        memset(vis, false, sizeof(vis));
        find(1, 0);//此时temp里面已经装了若干边缘结点
        ans = temp;
        memset(vis, false, sizeof(vis));
        maxh = 0;
        temp.clear();
        find(ans[0], 0);
        for (i = 0; i < temp.size(); i++)
        {
            ans.push_back(temp[i]);
        }
        sort(ans.begin(), ans.end());
        printf("%d\n", ans[0]);
        for (i = 1; i <ans.size(); i++)
        {
            if(ans[i]!=ans[i-1])
            printf("%d\n",ans[i]);
        }
    }
}