暴力_1021 Deepest Root (25 分)

1021 Deepest Root (25 分)

A graph which is connected and acyclic can be considered a tree. The hight 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

首先求解树的个树,这个可以深搜也可以 使用并查集,我的程序中使用的是并查集,最后只需要判断所有节点的per一共有多少种结果,即为含有多少个树

判断最深节点个数:首先确定一个节点,从该节点开始遍历整棵树,获取能达到的最深的结点集合,记为集合A;然后从集合A中任意一个结点出发遍历整棵树,获取能达到的最深顶点,记为结点集合B。集合A与B的并集就是所求结果。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <set>
#define INF 0x3f3f3f3f

using namespace std;
const int mod = 1e9+7;
const int maxn = 1e4+10;
typedef long long ll;

int n,head[maxn],next1[maxn*2],v[maxn*2],max_ans,per[maxn];
vector<int> ans;
set<int> s;
bool used[maxn];
void Add_edge(int x,int y,int& k)
{
    v[k] = y;next1[k] = head[x];head[x] = k++;
    v[k] = x;next1[k] = head[y];head[y] = k++;
}
int find_f(int x)
{
    return x==per[x]?x:per[x] = find_f(per[x]);
}
void Union(int x,int y)
{
    x = find_f(x);
    y = find_f(y);
    if(x != y)
        per[x] = y;
}
void Push()
{
    for(int i = 0;i < ans.size();i ++)
        s.insert(ans[i]);
}
int dfs(int p,int deep)
{
    bool flag = false;;
    for(int i = head[p];i != -1;i = next1[i]){
        if(!used[v[i]])
        {
            flag = true;
            used[v[i]] = true;
            dfs(v[i],deep+1);
            used[v[i]] = false;
        }
    }
    if(!flag)
    {
        if(deep > max_ans)
        {
            max_ans = deep,ans.clear();ans.push_back(p);
        }
        if(deep == max_ans)
            ans.push_back(p);
    }
}
int main()
{
    memset(head,-1,sizeof(head));
    int x,y,k=0;
    scanf("%d",&n);
    for(int i = 1;i <= n;i ++)per[i] = i;
    for(int i = 1;i < n;i ++)
    {
        scanf("%d%d",&x,&y);
        Add_edge(x,y,k);
        Union(x,y);
    }
    for(int i = 1;i <= n;i ++) s.insert(find_f(i));
    if(s.size()!= 1)
    {
        printf("Error: %d components\n",s.size());
        return 0;
    }
    s.clear();
    used[1] = true;
    dfs(1,1);
    Push();int pos = ans[0];
    ans.clear();memset(used,0,sizeof(used));used[pos] = true;
    dfs(pos,1);
    Push();
    for(set<int>::iterator it = s.begin();it != s.end();it ++)
        printf("%d\n",*it);
    return 0;
}

链式前向星中的数组忘记乘以2倍了,总是各种错误,就是没有段错误,莫名其妙的显示内存超限,emmmm,改了好久好久

参考博客

https://blog.csdn.net/hy971216/article/details/82252707

猜你喜欢

转载自blog.csdn.net/li1615882553/article/details/84573809
今日推荐