1021. Deepest Root (25)

Posted 给杰瑞一块奶酪~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1021. Deepest Root (25)相关的知识,希望对你有一定的参考价值。

A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree. Such a root is called the deepest root.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=10000) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N-1 lines follow, each describes an edge by given the two adjacent nodes‘ numbers.

Output Specification:

For each test case, print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers. In case that the given graph is not a tree, print "Error: K components" where K is the number of connected components in the graph.

Sample Input 1:
5
1 2
1 3
1 4
2 5
Sample Output 1:
3
4
5
Sample Input 2:
5
1 3
1 4
2 5
3 4
Sample Output 2:
Error: 2 components


先随便找个点找出离这个点最远的点,首先这些点是符合的,然后从中拿一点做同样操作。
可以这样考虑,最深的根至少存在两个,至少是两端一端一个,中间的点必定离其中一个或多个端点最远所以随便找个点a,找出的离这个点最远的点bi,bi一定符合,然后只需要再从这些点里拿出一个端点bk做同样操作就可以找出剩下满足的点ci。因为其他没找出来的点ci肯定是离第一次选的点a近一些,也就是离第一次找出的点bi远。所以只需要再用一个点bk就课可以找出来。
用了邻接表和深搜。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#define Max 10005
using namespace std;
int fir[Max*2],nex[Max*2],u[Max*2],v[Max*2];//双向邻接表
int vis[Max],vi[Max];//vis标记是否访问,vi标记是否已经被认定为满足条件的点 不重复记录
int maxd[Max],no,maxv,last;//last最初为1 maxd为空,方便更新整个数组 no为下标,第一次找完后  last更新为no  方便之后的查找对no进行更新 ,不影响之前找到的点
int n,cunion;//cunion记录连通分量
void dfs(int k,int height)
{
    if(height > maxv)
    {
        maxv = height;
        no = last;
        if(!vi[k])vi[k] = 1,maxd[no ++] = k;
    }
    else if(height == maxv && !vi[k])vi[k] = 1,maxd[no ++] = k;
    int p = fir[k];
    while(p != -1)
    {
        if(!vis[v[p]])
        {
            vis[v[p]] = 1;
            dfs(v[p],height + 1);
        }
        p = nex[p];
    }
}
int main()
{
    cin>>n;
    memset(fir,-1,sizeof(nex));
    for(int i = 0;i < n - 1;i ++)
    {
        cin>>u[i]>>v[i];
        u[i+n-1] = v[i];
        v[i+n-1] = u[i];
        nex[i] = fir[u[i]];
        fir[u[i]] = i;
        nex[i+n-1] = fir[u[i+n-1]];
        fir[u[i+n-1]] = i+n-1;
    }
    for(int i = 1;i <= n;i ++)
    {
        if(!vis[i])
        {
            cunion ++;
            vis[i] = 1;
            dfs(i,1);
        }
    }
    if(cunion != 1)cout<<"Error: "<<cunion<<" components"<<endl;
    else
    {
        last = no;
        memset(vis,0,sizeof(vis));
        memset(vi,0,sizeof(vi));
        for(int i = 0;i < last;i ++)
        vi[maxd[i]] = 1;
        dfs(maxd[0],1);
        sort(maxd,maxd+no);
        for(int i = 0;i < no;i ++)
            cout<<maxd[i]<<endl;
    }
}

 

以上是关于1021. Deepest Root (25)的主要内容,如果未能解决你的问题,请参考以下文章

PAT 1021. Deepest Root (25)

1021 Deepest Root (25 分)

1021 Deepest Root (25 分)(经典搜索)

1021. Deepest Root (25)

PAT (Advanced Level) 1021. Deepest Root (25)

PAT 1021 Deepest Root