PAT 1021. Deepest Root

题目:http://pat.zju.edu.cn/contests/pat-a-practise/1021

题解:

给N个点,N-1条边,先判断是否为树,如果不是树,输出有几块;如果是树,求符合条件的i是哪些(当第i个节点为树根时,树的高度最大)。

先用并查集求所给的是否为树,然后通过两次dfs求最长的树径,第二次dfs时就可以记录符合条件的i,最后结合第一次和第二次的结果,从小到大排序输出。

注:测试数据中有n=1的情况。

代码:

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAX 10005
int edge[MAX<<1];//表示第i条边的终点
int nextx[MAX<<1];//与第i条边同起点的下一条边的位置
int head[MAX<<1];//以i为起点的第一条边的储存位置
int pre[MAX];
bool visited[MAX];
int n;
int maxDeep;
int point;
set q,out;
void insert(int i,int a,int b)//a起点,b终点
{
    edge[i]=b;
    nextx[i]=head[a];
    head[a]=i;
}
int Find(int x)//查找
{
    if(pre[x]==x) return x;
    return pre[x]=Find(pre[x]);
}
void Union(int a,int b)//合并
{
    int x=Find(a);
    int y=Find(b);
    if(x!=y)
        pre[y]=x;
}
void dfs(int st,int deep)
{
    if(deep>maxDeep)
    {
        maxDeep=deep;
        point=st;
        q.clear();
        q.insert(st);
    }
    else if(deep==maxDeep)
        q.insert(st);
    visited[st]=true;
    for(int i=head[st]; i!=-1; i=nextx[i])
    {
        if(visited[edge[i]]==false)
            dfs(edge[i],deep+1);
    }
    visited[st]=false;
}
int main()
{
    int a,b;
    int countx=0;
    set::iterator iter;
    scanf("%d",&n);
    for(int i=0; i<=n; ++i)
        pre[i]=i;
    memset(nextx,-1,sizeof(nextx));
    memset(head,-1,sizeof(head));
    memset(edge,-1,sizeof(edge));
    for(int i=1; i<2*n-1; i+=2)
    {
        scanf("%d%d",&a,&b);
        Union(a,b);
        insert(i,a,b);
        insert(i+1,b,a);
    }
    for(int i=1; i<=n; ++i)
        if(pre[i]==i)
            ++countx;
    if(countx>1)
    {
        printf("Error: %d components\n",countx);
        return 0;
    }
    if(n==1)
    {
        printf("1\n");
        return 0;
    }
    memset(visited,false,sizeof(visited));
    maxDeep=0;
    dfs(1,0);
    memset(visited,false,sizeof(visited));
    for(iter=q.begin();iter!=q.end();++iter)
    {
        out.insert(*iter);
    }
    q.clear();
    maxDeep=0;
    a=point;
    dfs(point,0);
    for(iter=q.begin();iter!=q.end();++iter)
    {
        out.insert(*iter);
    }
    out.insert(a);
    for(iter=out.begin();iter!=out.end();++iter)
    {
        printf("%d\n",*iter);
    }
    return 0;
}

来源: http://blog.csdn.net/acm_ted/article/details/20146471

你可能感兴趣的:(PAT)