1.可以用并查集求无向图的连通图个数,也可以直接用dfs 然后要注
2.若是树 则相当于求树的最大直径 即 第一次dfs求出部分直径端点 第二次求出所有的直径端点
3.用set去重 不然好麻烦
//树的最大直径 :先用任一端点找出直径的一个端点 然后用该端点求出直径的其余端点
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
const int N = 10000+5;
vector<int> V[N], ans;
set<int> temp;
bool vis[N];
int pre[N];
int cnt;//连通分量个数
int Maxh= 1;
void init() {
ans.clear();
for(int i=0; i<N; i++) {
V[i].clear();
vis[i] = false;
pre[i] = i;
}
}
//用并查集求连通分量个数(需是无向图)
int Find(int a) {
return (a == pre[a])? a : (pre[a] = Find(pre[a]));
}
bool Union(int a, int b) {
a = Find(a), b = Find(b);
if(a == b) { //本就在一起
return false;
} else {
pre[a] = b;
return true;
}
}
void dfs(int a, int h) {
vis[a] = true;
if(h >= Maxh) {
if(h > Maxh) {
ans.clear();
}
// cout << h << "==" << Maxh <<"::"<< ans.size() << endl;
Maxh = h;
ans.push_back(a);
}
for(int i=0; i<V[a].size(); i++) {
if(!vis[V[a][i]]) {
dfs(V[a][i], h+1);
}
}
}
int main() {
int n;
init();
cin >> n;
cnt = n;
for(int i=0; i<n-1; i++) {
int a, b;
cin >> a >> b;
V[a].push_back(b);
V[b].push_back(a);
if(Union(a, b)) {
cnt--;
}
}
if(cnt > 1) {
printf("Error: %d components\n", cnt);
} else { //求树的最大直径 以及直径的端点
dfs(1, 1);//先求出一个端点
int tmp = ans[0];
memset(vis, false, sizeof(vis));
for(int i=0; i<ans.size(); i++){
temp.insert(ans[i]);
}
ans.clear();
dfs(tmp, 1);
ans.push_back(tmp);
for(int i=0; i<ans.size(); i++){
temp.insert(ans[i]);
}
for(set<int>:: iterator it=temp.begin(); it!=temp.end(); it++) {
cout << *it << endl;
}
}
return 0;
}