题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805482919673856
参考:https://www.liuchuo.net/archives/2348
思路
- 先判断有几个连通图
- 有两个及以上:输出连通量
- 只有一个:先从一个结点dfs后保留最高高度拥有的结点们,然后从这些结点中的其中任意一个开始dfs得到最高高度的结点们,这两个结点集合的并集就是所求
- 第三点结论好像有证明,我试过把第二个集合去了,只有两个测试点没过
代码
#include<vector>#include<algorithm>#include<set>#include<cstdio>#include<iostream>using namespace std;const int maxn = 10010;vector<int> G[maxn], temp;bool vis[maxn];set<int> s;int maxheight = 0;void dfs(int v, int height){if(height > maxheight){temp.clear();temp.push_back(v);maxheight = height;} else if(height == maxheight){temp.push_back(v);}vis[v] = true;for(int i = 0; i < G[v].size(); i++){if(vis[G[v][i]] == false) dfs(G[v][i], height + 1);}}int main(){int n;scanf("%d", &n);for(int i = 0; i < n - 1; i++){int a, b;scanf("%d%d", &a, &b);G[a].push_back(b);G[b].push_back(a);}int a, b, cnt = 0, s1 = 0;for(int i = 1; i <= n; i++){if(vis[i] == false){dfs(i, 1);//这个时候已经遍历完了,得到最大高度if(i == 1){if(temp.size()!=0) s1 = temp[0];for(int j = 0; j < temp.size(); j++){s.insert(temp[j]);}}cnt++;}}if(cnt >= 2){printf("Error: %d components",cnt);} else {temp.clear();maxheight = 0;fill(vis, vis + 10010, false);dfs(s1, 1);for(int i = 0; i < temp.size(); i++){s.insert(temp[i]);}for(auto it = s.begin(); it != s.end(); it++){printf("%d\n", *it);}}return 0;}
