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 (≤104) 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
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <algorithm> #include <iostream> #include <string.h> #include <queue> #include <string> #include <set> #include <map> using namespace std; const int maxn = 10010; const int inf = 99999999; int n; int depth[maxn] = { 0 }; bool vis[maxn] = { false }; struct node { int id; int depth; }nodes[maxn]; vector<int> adj[maxn]; void bfs(int v) { queue<node> q; q.push(nodes[v]); vis[v] = true; while (!q.empty()) { node u = q.front(); q.pop(); for (int i = 0; i < adj[u.id].size(); i++) { if (vis[adj[u.id][i]] == false) { nodes[adj[u.id][i]].depth = u.depth + 1; q.push(nodes[adj[u.id][i]]); vis[adj[u.id][i]] = true; if (nodes[adj[u.id][i]].depth > depth[v]) { depth[v] = nodes[adj[u.id][i]].depth; } } } } } bool bfs_c(int v) { fill(vis, vis + maxn, false); queue<int> q; q.push(v); vis[v] = true; int count = 1; while (!q.empty()) { int u = q.front(); q.pop(); vis[u] = true; for (int i = 0; i <adj[u].size(); i++) { if (vis[adj[u][i]] == false) { q.push(adj[u][i]); count++; if (count > n)return false; } } } return true; } int bfsTrave() { fill(vis, vis + maxn, false); int count = 0; for (int i = 1; i <= n; i++) { if (vis[i] == false) { bfs(i); count++; } } return count; } int main() { cin >> n; for (int i = 1; i < n; i++) { int c1, c2; cin >> c1 >> c2; adj[c1].push_back(c2); adj[c2].push_back(c1); } for(int i=1;i<=n;i++){ nodes[i].id = i; nodes[i].depth = 1; } int k = bfsTrave(); if (k > 1)printf("Error: %d components", k); else { if (!bfs_c(1))printf("Error: %d components", k); else { for (int i = 1; i <= n; i++) { fill(vis, vis + maxn, false); for (int i = 1; i <= n; i++) { nodes[i].depth = 1; } bfs(i); } int max_d = 0; vector<int> maxi; for (int i = 1; i <= n; i++) { if (depth[i] > max_d) { max_d = depth[i]; maxi.clear(); maxi.push_back(i); } else if (depth[i] == max_d) { maxi.push_back(i); } } for (int i = 0; i < maxi.size(); i++) { printf("%d ", maxi[i]); } } } system("pause"); }
注意点:考察整个图的遍历以及有环无环图的判断。这里判断有没有环我是通过bfs的加入队列个数超过n来判断的。每个节点遍历一遍,找到最大深度再输出。
ps:看了别人的思路,发现自己想多了,n个节点n-1条边,若只有1个联通块就不会有环,所以那个都是白判断的。
ps2:随便找一个节点dfs找到最深的那些节点,再从那些节点里挑一个dfs找到最深的节点,并集就是所有最深的节点,不需要每个节点都做一次搜索。