接続された非巡回グラフはツリーと見なすことができます。木の高さは、選択したルートによって異なります。これで、最も高いツリーになるルートを見つけることになっています。このようなルートは、最も深いルートと呼ばれます。
入力仕様:
各入力ファイルには、1つのテストケースが含まれています。いずれの場合も、最初の行にはノードの数である正の整数N(≤104)が含まれているため、ノードには1からNまでの番号が付けられます。ノードの番号。
出力仕様:
テストケースごとに、最も深いルートを1行に印刷します。そのようなルートが一意でない場合は、番号の昇順で印刷してください。与えられたグラフがツリーでない場合に、印刷Error: K components
場所K
グラフにおける連結成分の数です。
サンプル入力1:
5
1 2
1 3
1 4
2 5
サンプル出力1:
3
4
5
サンプル入力2:
5
1 3
1 4
2 5
3 4
サンプル出力2:
Error: 2 components
アイデア
最初に接続されたセットの数を判断し、2より大きい出力を出力します。次に、PATはブルートフォース、各ノードのブルートフォース検索、各ノードの最大値の検索、最大値の取得、最後に最大値の出力を行うことができます。Niuke.comで、それは2回だけ必要ですdfsは大丈夫です。
コード
暴力的なバージョン
#include <iostream>
#include <vector>
using namespace std;
vector<int> data[10005];
int vis[10005];
int res[10005];
int maxdepth; // 记录最大深度
void connect_set(int u) // 求连通集
{
if (vis[u])
return;
vis[u] = 1;
for (int i = 0; i < data[u].size(); i++)
connect_set(data[u][i]);
}
void union_set(){
}
void dfs(int u, int depth)
{
if (vis[u])
return;
if (depth > maxdepth)
maxdepth = depth;
vis[u] = 1;
for (int i = 0; i < data[u].size(); i++)
dfs(data[u][i], depth + 1);
}
int main()
{
int n;
cin >> n;
int u, v;
for (int i = 1; i <= n - 1; i++)
{
cin >> u >> v;
data[u].push_back(v);
data[v].push_back(u);
}
if (n==1 || n == 0) {
cout << n << endl; return 0;}
int connnect_set_size = 0;
// for (int i = 1; i <= n; i++)
// {
// for(int j=0; j<data[i].size(); j++)
// cout << data[i][j] << " ";
// cout <<endl;
// }
for (int i = 1; i <= n; i++)
{
if (vis[i] == 0)
{
connect_set(i);
connnect_set_size++;
}
}
if (connnect_set_size > 1)
cout << "Error: "<< connnect_set_size << " components" << endl;
else
{
// for (int i = 1; i <= n; i++)
// vis[i] = 0;
for (int i = 1; i <= n; i++)
{
maxdepth = 0;
fill(vis, vis + n + 1, 0);
dfs(i, 0);
res[i] = maxdepth;
}
int last_depth = 0;
for (int i = 1; i <= n; i++)
{
if (res[i] > last_depth)
last_depth = res[i];
}
for (int i = 1; i <= n; i++)
if (res[i] == last_depth)
cout << i << endl;
}
return 0;
}
// 参考柳婼
#include <iostream>
#include <vector>
#include <set>
using namespace std;
vector<vector<int>> data;
bool visit[10005];
int max_height; // 记录最大高度
vector<int> temp; // 保存从一个节点dfs下去深度最大的多个节点
set<int> res; //记录结果
void dfs(int node, int height)
{
if (visit[node])
return;
if (max_height < height)
{
max_height = height;
temp.clear();
temp.push_back(node);
}
if (max_height == height)
temp.push_back(node);
visit[node] = true;
for (int i = 0; i < data[node].size(); i++)
{
dfs(data[node][i], height + 1);
}
}
int main()
{
max_height = 0;
int n;
cin >> n;
data.resize(n + 1);
int u, v;
for (int i = 1; i <= n - 1; i++)
{
cin >> u >> v;
data[u].push_back(v);
data[v].push_back(u);
}
int cnt = 0; // 记录连通块的个数
for (int i = 1; i <= n; i++)
{
if (visit[i] == false)
{
dfs(i, 1);
if (i == 1)
{
for (int j = 0; j < temp.size(); j++)
{
res.insert(temp[j]);
}
}
cnt++; // 说明遍历一次后没有完成遍历过
}
}
if (cnt > 1)
{
cout << "Error: " << cnt << " components" << endl;
}
else
{
max_height = 0; // 记得要重新值为0,因为是重新找一个最大高度的
fill(visit, visit + n + 1, false); // 记得要重置
dfs(temp[0], 1);
for (int j = 0; j < temp.size(); j++)
res.insert(temp[j]);
for (auto it = res.begin(); it != res.end(); it++)
{
cout << *it << endl;
}
}
return 0;
}