zoukankan      html  css  js  c++  java
  • 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 (<=10000) 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
    

    先随便找个点找出离这个点最远的点,首先这些点是符合的,然后从中拿一点做同样操作。
    可以这样考虑,最深的根至少存在两个,至少是两端一端一个,中间的点必定离其中一个或多个端点最远所以随便找个点a,找出的离这个点最远的点bi,bi一定符合,然后只需要再从这些点里拿出一个端点bk做同样操作就可以找出剩下满足的点ci。因为其他没找出来的点ci肯定是离第一次选的点a近一些,也就是离第一次找出的点bi远。所以只需要再用一个点bk就课可以找出来。
    用了邻接表和深搜。
    代码:
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #define Max 10005
    using namespace std;
    int fir[Max*2],nex[Max*2],u[Max*2],v[Max*2];//双向邻接表
    int vis[Max],vi[Max];//vis标记是否访问,vi标记是否已经被认定为满足条件的点 不重复记录
    int maxd[Max],no,maxv,last;//last最初为1 maxd为空,方便更新整个数组 no为下标,第一次找完后  last更新为no  方便之后的查找对no进行更新 ,不影响之前找到的点
    int n,cunion;//cunion记录连通分量
    void dfs(int k,int height)
    {
        if(height > maxv)
        {
            maxv = height;
            no = last;
            if(!vi[k])vi[k] = 1,maxd[no ++] = k;
        }
        else if(height == maxv && !vi[k])vi[k] = 1,maxd[no ++] = k;
        int p = fir[k];
        while(p != -1)
        {
            if(!vis[v[p]])
            {
                vis[v[p]] = 1;
                dfs(v[p],height + 1);
            }
            p = nex[p];
        }
    }
    int main()
    {
        cin>>n;
        memset(fir,-1,sizeof(nex));
        for(int i = 0;i < n - 1;i ++)
        {
            cin>>u[i]>>v[i];
            u[i+n-1] = v[i];
            v[i+n-1] = u[i];
            nex[i] = fir[u[i]];
            fir[u[i]] = i;
            nex[i+n-1] = fir[u[i+n-1]];
            fir[u[i+n-1]] = i+n-1;
        }
        for(int i = 1;i <= n;i ++)
        {
            if(!vis[i])
            {
                cunion ++;
                vis[i] = 1;
                dfs(i,1);
            }
        }
        if(cunion != 1)cout<<"Error: "<<cunion<<" components"<<endl;
        else
        {
            last = no;
            memset(vis,0,sizeof(vis));
            memset(vi,0,sizeof(vi));
            for(int i = 0;i < last;i ++)
            vi[maxd[i]] = 1;
            dfs(maxd[0],1);
            sort(maxd,maxd+no);
            for(int i = 0;i < no;i ++)
                cout<<maxd[i]<<endl;
        }
    }
  • 相关阅读:
    线性单链表动态内存分配(C语言实现)
    线性顺序表动态内存分配(C语言实现)
    Linux-v01天-课堂笔记
    博客园之自定义博客(美化+播放器)
    递归练习
    算法基础练习-_06 二进制小数
    算法基础练习-_05将整数的奇偶位互换
    算法基础练习-_03 1的个数
    算法基础练习-_01找出唯一成对的数
    常用算法之快速排序
  • 原文地址:https://www.cnblogs.com/8023spz/p/8012678.html
Copyright © 2011-2022 走看看