1021 Deepest Root (25 分)

11 篇文章 0 订阅
1 篇文章 0 订阅

题目链接

https://pintia.cn/problem-sets/994805342720868352/problems/994805482919673856

题目描述

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 (≤10​4​​) 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

解题思路

题目:该题条件给的简单,开始思考的时候没有考虑n-1条边,把题目想复杂了。

n-1条边的无向图来说,如果整个图集只有一个图,那么一定没有回环(开始想成有向图并使用拓扑排序判断是否回环,多此一举)。如果不止有一个图,那么输出图的个数。

关键思路:

       1、判断图:并查集。find和merage的运用。使用set判断有多少个集合。如果只有一个集合,那么是生成树,否则直接输出错误,和该图集集合树。

       2、使用dfs求高度:对于每一个节点进行一次深度搜索,输出他的最大高度,对于一个遍历过的节点我们进行高度的保存,防止冗余计算,增加时间复杂度。

解题代码

#include <iostream>
#include<bits/stdc++.h>
#define rep(i,s,e) for(int i = s;i<e;i++)
using namespace std;
const int MAXSIZE = 10001;
int parent[MAXSIZE];
int isVer[MAXSIZE];
int n;
struct edge{
    int v;
    edge * next;
};
struct teHi{
    int num;
    int hi;
};
edge g[MAXSIZE];
int maxHi[MAXSIZE];
int dfs(int i,int h){
    edge *e = g[i].next;
    int subH = h;
    isVer[i] = 1;
    while(e!=NULL){
        if(maxHi[e->v]!=-1){
            subH = max(subH,h+maxHi[e->v]);
            e=e->next;
            continue;
        }else{
            if(isVer[e->v]==0){
                subH = max(subH,dfs(e->v,h+1));
            }
        }
        e = e->next;
    }
    isVer[i] = 0;
    return subH;
}
int findp(int i){
    if(parent[i]==i){
        return i;
    }
    return parent[i] = findp(parent[i]);
}
void merage(int i,int j){
    int pi = findp(i);
    int pj = findp(j);
    if(pi!=pj) parent[pj] = pi;
}
bool cmp(teHi t1,teHi t2){
    if(t1.hi!=t2.hi){
        return t1.hi>t2.hi;
    }else{
        return t1.num<t2.num;
    }
}
void getRe(){
    //1、判断连通分量
    int sum =0;
    set<int>s;
    rep(i,1,n+1){
        int p = findp(i);
        if(s.count(p)==0){
            sum++;
            s.insert(p);
          //  cout<<p<<endl;
        }
    }
    if(sum==1){
        // dfs遍历
        teHi te[n+1];
        rep(i,1,n+1){
            te[i].num=i;
            te[i].hi=dfs(i,0);
        }
        sort(te+1,te+n+1,cmp);
        int ma = te[1].hi;
        int sum = 1;
        rep(i,2,n+1){
            if(te[i].hi==ma) sum++;
            else break;
        }
        rep(i,1,sum+1){
            cout<<te[i].num;
            if(i!=sum) cout<<endl;
        }
    }else{
        printf("Error: %d components",sum);
    }
}
void init(){
    cin>>n;
    rep(i,1,n+1) {parent[i] = i;
        maxHi[i] = -1;
    }
    rep(i,0,n-1){
        int u,v;
        cin>>u>>v;
        edge *e = new edge;
        edge *e1 = new edge;
        e->v = v;
        e1->v = u;
        e->next = g[u].next;
        g[u].next = e;
        e1->next = g[v].next;
        g[v].next = e1;
        merage(u,v);
    }
}
int main()
{
    init();
    getRe();
  //  rep(i,1,n+1) cout<<parent[i]<<" ";
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值