PAT 1021 Deepest Root (25 分)

#include <cstdio>
#include <set>
using namespace std;
set<int> g[100010],temp,ans;
int father[100010];
//isroot[i]为true表示i为根节点
bool isroot[100010];
int findfather(int x)
{
    int a=x;
    while(father[x]!=x)
        x=father[x];
    while(father[a]!=a)
    {
        int z=a;
        a=father[a];
        father[a]=x;
    }
    return x;
}
void Union(int a,int b)
{
    int faa=findfather(a);
    int fab=findfather(b);
    if(faa!=fab)
        father[faa]=fab;
    return;
}
//将所有节点的父节点对应isroot置为true(因为压缩了路径,若一个图连通,其余n-1个节点均有同一个父节点)
//之后计算isroot=true的节点个数,即为连通分量个数
int calblock(int n)
{
    int block=0;
    for(int i=1;i<=n;i++)
        isroot[findfather(i)]=true;
    for(int i=1;i<=n;i++)
    {
        if(isroot[i]==true)
            block++;
    }
    return block;
}
int maxh=0;
//两次DFS,取并集
void DFS(int u,int height,int pre)
{
    if(height>maxh)
    {
        temp.clear();
        temp.insert(u);
        maxh=height;
    }
    else if(height==maxh)
        temp.insert(u);
    for(set<int>::iterator it=g[u].begin();it!=g[u].end();it++)
    {
        //避免走回头路
        if(*it==pre)
            continue;
        DFS(*it,height+1,u);
    }
}
int main()
{
    int a,b,n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        father[i]=i;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&a,&b);
        g[a].insert(b);
        g[b].insert(a);
        Union(a,b);
    }
    int block=calblock(n);
    if(block!=1)
        printf("Error: %d components\n",block);
    else
    {
        DFS(1,1,-1);
        ans=temp;
        set<int>::iterator ansbegin=ans.begin();
        DFS(*ansbegin,1,-1);
        for(set<int>::iterator it=temp.begin();it!=temp.end();it++)
            ans.insert(*it);
        for(set<int>::iterator it=ans.begin();it!=ans.end();it++)
            printf("%d\n",*it);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值