1021 Deepest Root
题目大意
先看下有多少个连通图,大于1个就直接输出不成立,等于1就可以看下最深的结点数有多少个
算法思想
- 就是dfs,先用dfs看下有多少个连通图,大于1个就输出错误
- 等于1个就对每个结点进行dfs,期间返回每个结点的最大深度,找到最大的深度,加入最大深度的结点,最后输出
- 第三个测试点有坑,估计这个图巨大,用的邻接表才过,不过好像柳神用的一种十分奇妙的数学方法,可以大大降低时间复杂度,但我还是用的我的土办法。
代码
#include<iostream>
#include<vector>
#include<map>
using namespace std;
vector<int>root;
vector<vector<int>>graph;//邻接表,不然会超时
vector<bool>t;
int dfs(int k,int high)//深度优先遍历
{
int h=0,max=high;
t[k] = true;
for (int i = 0; i < graph[k].size(); i++)
if (!t[graph[k][i]])
{
h = dfs(graph[k][i], high + 1);
if (h > max)
max = h;
}
return max;
}
int main()
{
int i,n, sum = 0;
cin >> n;
t.resize(n);
graph.resize(n);
fill(t.begin(), t.end(), false);
for (int i = 0; i < n - 1; i++)
{
int a, b;
cin >> a >> b;
graph[a - 1].push_back(b-1);
graph[b - 1].push_back(a-1);
}
for (i = 0; i < n; i++)//看下连通图的个数
{
if (!t[i])
{
sum++;
dfs(i,0);
}
}
if (sum != 1)
{
cout << "Error: " << sum << " components";
return 0;
}
int deep=0;
for (i = 0; i < n; i++)//看一下每个结点的深度
{
fill(t.begin(), t.end(), false);
int dp = dfs(i, 1);
if (deep < dp)//看下是否为更深
{
root.clear();
root.push_back(i + 1);
deep = dp;
}
else if (deep == dp)
root.push_back(i+1);
}
for (i = 0; i < root.size(); i++)
cout << root[i] << endl;
return 0;
}