码迷,mamicode.com
首页 > 其他好文 > 详细

1021 Deepest Root (25分)

时间:2021-01-27 13:11:33      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:corn   one   erro   roo   统计   sizeof   line   lin   class   

树的直径+统计连通块数。

和树的直径的模板题不同的是要求出所有能够构成直径两个端点的点,即为最深的根。

注意对\(n=1\)的特殊处理,这个corner case还是挺好想的,第一次交\(23\)分,调试一下就发现了。

由于要从小到大输出所有最深的根,故将它们全部插入集合中输出。

连通分量直接dfs统计就行,需要一个判重数组,也可以并查集。

const int N=10010;
vector<int> g[N];
vector<int> node;
int d[N];
bool vis[N];
int n;
int far;
set<int> S;

void dfs(int u,int fa)
{
    vis[u]=true;
    for(int i=0;i<g[u].size();i++)
    {
        int j=g[u][i];
        if(j == fa) continue;
        if(!vis[j])
        {
            d[j]=d[u]+1;
            if(d[j] > d[far])
            {
                node.clear();
                node.pb(j);
                far=j;
            }
            else if(d[j] == d[far])
                node.pb(j);
    
            dfs(j,u);
        }
    }
}

int main()
{
    cin>>n;

    for(int i=0;i<n-1;i++)
    {
        int a,b;
        cin>>a>>b;
        g[a].pb(b);
        g[b].pb(a);
    }

    int cnt=0;
    for(int i=1;i<=n;i++)
        if(!vis[i])
        {
            dfs(i,-1);
            if(i == 1)
            {
                if(!node.size()) node.pb(1);//corner case
                for(int i=0;i<node.size();i++) S.insert(node[i]);
            }
            cnt++;
        }
    
    if(cnt >= 2) printf("Error: %d components\n",cnt);
    else
    {
        d[far]=0;
        node.clear();
        memset(vis,0,sizeof vis);
        dfs(far,-1);
        for(int i=0;i<node.size();i++) S.insert(node[i]);

        for(auto t:S) cout<<t<<endl;
    }

    //system("pause");
    return 0;
}

并查集

const int N=10010;
vector<int> g[N];
vector<int> node;
int d[N];
int p[N];
int n;
int far;
set<int> S;

int find(int x)
{
    if(x != p[x]) p[x]=find(p[x]);
    return p[x];
}

void dfs(int u,int fa)
{
    for(int i=0;i<g[u].size();i++)
    {
        int j=g[u][i];
        if(j == fa) continue;

        d[j]=d[u]+1;
        if(d[j] > d[far])
        {
            node.clear();
            node.pb(j);
            far=j;
        }
        else if(d[j] == d[far])
            node.pb(j);

        dfs(j,u);
    }
}

int main()
{
    cin>>n;
    
    for(int i=1;i<=n;i++) p[i]=i;

    for(int i=0;i<n-1;i++)
    {
        int a,b;
        cin>>a>>b;
        g[a].pb(b);
        g[b].pb(a);
        int pa=find(a),pb=find(b);
        p[pa]=pb;
    }

    int cnt=0;
    for(int i=1;i<=n;i++) 
        if(p[i] == i)
            cnt++;
            
    if(cnt >= 2) printf("Error: %d components\n",cnt);
    else
    {
        dfs(1,-1);
        if(!node.size()) node.pb(1);
        for(int i=0;i<node.size();i++) S.insert(node[i]);
        
        d[far]=0;
        node.clear();
        
        dfs(far,-1);
        for(int i=0;i<node.size();i++) S.insert(node[i]);

        for(auto t:S) cout<<t<<endl;
    }

    //system("pause");
    return 0;
}

1021 Deepest Root (25分)

标签:corn   one   erro   roo   统计   sizeof   line   lin   class   

原文地址:https://www.cnblogs.com/fxh0707/p/14327987.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!