int bfs()
{
queue<int> q;
q.push(1);
int ret = 0;
while (q.size())//队列有数就进行循环
{
int sz = q.size();
ret = max(ret, sz);//找最大
while (sz--)//将上层的数出队列
{
int num = q.front();
q.pop();
for (auto e : edges[num])//让子结点入队列
{
q.push(e);
}
}
}
return ret;
}
由于计算机不像我们人一样能分辨在哪个结点进行分叉能得到最短路径,所以我们统一以根节点(1)为终止位置。首先我们用一个数组 fa 储存每一个结点的父结点(因为我们先前的数组只允许从上往下寻找数),再开一个数组 dist 存储每个结点之间的距离。以u结点为起始点,它到它父结点的距离就等于该点的距离加上1,再将该结点u设置为其父结点,一直遍历到根结点(1)停止。接下来我们找到v,创建一个len变量记录边数,只要v不等于根结点或者 dist[v] 内的数据为0,就让v等于它的父结点。当dist[v] 内不为0时,说明走到了分叉口,就停止循环。
最后我们将 dist[v] * 2 + len 输出就是最终答案。
最后放上完整代码:
样例代码:
cpp复制代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int N = 110;
vector<int> edges[N];
int dist[N], fa[N];
int dfs1(int root)
{
int ret = 0;
for (auto e : edges[root])
{
ret = max(ret, dfs1(e));
}
return ret + 1;
}
int bfs()
{
queue<int> q;
q.push(1);
int ret = 0;
while (q.size())//队列有数就进行循环
{
int sz = q.size();
ret = max(ret, sz);//找最大
while (sz--)//将上层的数出队列
{
int num = q.front();
q.pop();
for (auto e : edges[num])//让子结点入队列
{
q.push(e);
}
}
}
return ret;
}
int main()
{
int n;
cin >> n;
for (int i = 1; i < n; i++)
{
int a, b;
cin >> a >> b;
edges[a].push_back(b);
fa[b] = a;
}
int get1 = dfs1(1);
cout << get1 << endl;
int get2 = bfs();
cout << get2 << endl;
int u, v;//结点
cin >> u >> v;
while (u != 1)//算结点到1的距离
{
dist[fa[u]] = dist[u] + 1;
u = fa[u];
}
int len = 0;
while (v != 1 && dist[v] == 0)
{
len++;
v = fa[v];
}
cout << len + dist[v] * 2 << endl;
return 0;
}