PAT_A1021#Deepest Root

Source:

PAT A1021 Deepest Root (25 分)

Description:

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 (≤) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N1lines 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 componentswhere 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

Keys:

Attention:

  • 邻接矩阵存储图的规模要小于1e3,否则用邻接表存储

Code:

  1 /*
  2 Data: 2019-05-18 19:50:30
  3 Problem: PAT_A1021#Deepest Root
  4 AC: 45:38
  5 
  6 题目大意:
  7 寻找无环图中深度最大的生成树
  8 输入:
  9 第一行给出结点数N<1e4(结点从1~N)
 10 接下来N-1行给出存在边的两结点V1和V2
 11 输出:
 12 给出最大深度生成树的根结点,不唯一从小到大依次输出根结点。
 13 若图不连通则给出连通分量个数
 14 
 15 基本思路:
 16 从任意顶点开始遍历全图,root记录所能达到的最大深度及其顶点;
 17 再从root中任选一顶点,再次遍历全图,leaf记录所能达到的最大深度及顶点;
 18 如果图连通的话,
 19 生成树的最大深度就是第二次遍历全图所能达到的最大深度;
 20 the deepest root就是root+leaf的并集
 21 */
 22 
 23 #include<cstdio>
 24 #include<algorithm>
 25 #include<set>
 26 #include<vector>
 27 using namespace std;
 28 const int M=1e4;
 29 int vis[M],n,depth,f;
 30 set<int> root,leaf;
 31 vector<int> grap[M];
 32 
 33 void DFS(int u, int deep)
 34 {
 35     vis[u]=1;
 36     if(deep > depth)
 37     {
 38         depth=deep;
 39         if(f)
 40         {
 41             root.clear();
 42             root.insert(u);
 43         }
 44         else
 45         {
 46             leaf.clear();
 47             leaf.insert(u);
 48         }
 49     }
 50     else if(deep == depth)
 51         if(f)   root.insert(u);
 52         else    leaf.insert(u);
 53 
 54     for(int i=0; i<grap[u].size(); i++)
 55     {
 56         int v = grap[u][i];
 57         if(vis[v]==0)
 58             DFS(v,deep+1);
 59     }
 60 }
 61 
 62 int Travel()
 63 {
 64     int block=0;
 65     fill(vis,vis+M,0);
 66     for(int v=1; v<=n; v++)
 67     {
 68         if(vis[v]==0)
 69         {
 70             DFS(v,1);
 71             block++;
 72         }
 73     }
 74     return block;
 75 }
 76 
 77 int main()
 78 {
 79 #ifdef  ONLINE_JUDGE
 80 #else
 81     freopen("Test.txt", "r", stdin);
 82 #endif // ONLINE_JUDGE
 83 
 84     scanf("%d", &n);
 85     for(int i=1; i<n; i++)
 86     {
 87         int v1,v2;
 88         scanf("%d%d", &v1,&v2);
 89         grap[v1].push_back(v2);
 90         grap[v2].push_back(v1);
 91     }
 92     depth=0;f=1;
 93     int block = Travel();
 94     if(block > 1)
 95         printf("Error: %d components\n", block);
 96     else
 97     {
 98         fill(vis,vis+M,0);f=0;
 99         DFS(*root.begin(),1);
100         for(auto it=leaf.begin(); it!=leaf.end(); it++)
101             root.insert(*it);
102         for(auto it=root.begin(); it!=root.end(); it++)
103             printf("%d\n", *it);
104     }
105 
106     return 0;
107 }

 

转载于:https://www.cnblogs.com/blue-lin/p/10887069.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值