【PAT】 Deepest Root (DFS)

来源:互联网 发布:淘宝电脑主机才500多 编辑:程序博客网 时间:2024/06/06 03:57

【PAT】 Deepest Root (DFS)


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 . 

输入描述:
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.


输出描述:
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.

输入例子:
51 21 31 42 5

输出例子:
345

很巧妙的两边搜索。

首先题意:n个点搭建n-1条边。如果不构成树(一定构成了两个以上的连通图) 直接输出图的数量(用并查集解决即可

否则,已知树的深度是树根到叶子的最远距离,输出能得到最深的树的根节点编号。如果有多个结点可满足,都输出。


更进一步的,如果某个点u作为根,那么最深的那些叶子与u,一定是树中距离最远的点对。

这样不论我们以谁为根,最深的那些点,一定包括在上面提到的点对中。(*第一个迷

除了这些最深的点以外,相对于这些点距离最远的点,也是所需要得点(*第二个迷


想通了,求的话就好办了,两边dfs

预先选任意一个点为根

第一遍dfs找到最深的点(可能有多个),同时记录一下路径

第二遍dfs找到相对第一个dfs找到的那些点而言最远的点,可通过第一遍dfs标记的路径来找。如果在路径上,距离-1,否则距离+1


代码如下:

#include <iostream>#include <cmath>#include <vector>#include <cstdlib>#include <cstdio>#include <cstring>#include <queue>#include <stack>#include <list>#include <algorithm>#include <map>#include <set>#define LL long long#define Pr pair<int,int>#define fread() freopen("in.in","r",stdin)#define fwrite() freopen("out.out","w",stdout)  using namespace std;const int INF = 0x3f3f3f3f;const int msz = 10000;const int mod = 1e9+7;const double eps = 1e-8;  struct Edge{    int v,next;};  int n;int pre[10010];int head[10010];Edge eg[23333];int dep[10010],to[10010];int tp,cnt,mx,len[10010],cc;  void init(){    for(int i = 1; i <= n; ++i) pre[i] = i;}  int Find(int x){    return pre[x] == x? pre[x]: (pre[x] = Find(pre[x]));}  void Add(int u,int v){    eg[tp].v = v;    eg[tp].next = head[u];    head[u] = tp++;}  void dfs1(int u,int pre,int depth){    dep[u] = depth;    to[u] = u;      for(int i = head[u]; i != -1; i = eg[i].next)    {        if(eg[i].v == pre) continue;        dfs1(eg[i].v,u,depth+1);        if(dep[to[eg[i].v]] > dep[to[u]]) to[u] = to[eg[i].v];    }    if(dep[u] == mx) cnt++;    else if(dep[u] > mx)    {        mx = dep[u];        cnt = 1;    }}  void dfs2(int u,int pre,int l,bool op){    len[u] = l;    cc = max(cc,len[u]);      if(!op)    {        cnt = 0;        for(int i = head[u]; i != -1; i = eg[i].next)        {            if(eg[i].v == pre) continue;            if(dep[to[eg[i].v]] == mx) cnt++;        }        if(cnt > 1) op = 1;    }      for(int i = head[u]; i != -1; i = eg[i].next)    {        if(eg[i].v == pre) continue;        if(!op && dep[to[eg[i].v]] == mx) dfs2(eg[i].v,u,l-1,op);        else dfs2(eg[i].v,u,l+1,op);    }}  int main(){    //fread();    //fwrite();      int u,v,k,r;    scanf("%d",&n);    init();      memset(head,-1,sizeof(head));      for(int i = 1; i < n; ++i)    {        scanf("%d%d",&u,&v);        k = Find(u);        r = Find(v);        if(k != r) pre[r] = k;        Add(u,v);        Add(v,u);    }      cnt = 0;    for(int i = 1; i <= n; ++i)        if(Find(i) == i) cnt++;      if(cnt > 1)    {        printf("Error: %d components\n",cnt);    }    else    {        mx = -1;        dfs1(1,1,0);              cc = -1;        dfs2(1,1,mx,0);        for(int i = 1; i <= n; ++i)        {            if(dep[i] == mx || len[i] == cc) printf("%d\n",i);        }    }      return 0;}





0 0
原创粉丝点击