【问题标题】:Find the Largest Distance between nodes of a Tree ? Can someone explain me the approach for this找到树的节点之间的最大距离?有人可以解释一下这个方法吗
【发布时间】:2021-11-02 13:06:32
【问题描述】:

Link to problem
InterviewBit解决问题

int Solution::solve(vector<int> &A)
{
   vector<int> hgt(A.size(),0);
   int ans=0,maxx=0;
   for(int i=A.size()-1;i>0;i--)
   {
       ans=max(ans,hgt[A[i]]+hgt[i]+1);
       hgt[A[i]]=max(hgt[i]+1,hgt[A[i]]);
   }
   return ans;
}

有人可以向我解释上面的代码以及他们所说的方法如下:

  1. 选择任何节点 u。
  2. 找到离u最远的节点,称之为x。
  3. 找到离x最远的节点,称之为q。
  4. 答案是从 x 到 q 的路径长度。

【问题讨论】:

  • 请在问题中提供minimal reproducible example,不要依赖外部链接
  • 您的代码似乎不正确,请引用真实的。
  • @CiaPan 我已经编辑了上面的代码。以上代码取自 InterviewBit 的完整解决方案选项卡。这个据说是最快的。
  • 您没有指定 A 向量包含的内容。并且代码似乎依赖于关于向量内容的特定假设。顺便说一句,它声明了一个它从不使用的变量。

标签: c++ algorithm graph tree graph-algorithm


【解决方案1】:

基本上问题是找出一棵树的直径。

树的直径 - 它是树中两个节点之间的最长路径 树。

最长的路径总是出现在两个叶子节点之间。

比方说,你已经从给定的数组中创建了树。

现在您可以使用 2 个 DFS 或 BFS 来做到这一点。

程序:

  1. 从随机节点启动 BFS(假设我们从根节点运行)和 找出离它最远的节点。让最远的节点是 X。它是 清楚 X 永远是叶节点。

  2. 现在如果我们从 X 启动 BFS 并检查离它最远的节点(比如 我们之前做过),我们会得到树的直径。

示例代码:

#define MAX 40001

vector<int> adj[MAX];
int dist[MAX];
int totalNode;

pair<int, int> _bfs(int startingNode) {
    for(int i=0; i <= totalNode; i++) {
        dist[i] = 0;
    }

    dist[startingNode] = 1;
    int maxDistance = 0, farthestNode;
    queue<int> q;
    q.push(startingNode);

    while(!q.empty()) {
        int currNode = q.front();
        q.pop();

        int sz = adj[currNode].size();
        for(int i = 0; i < sz; i++) {
            int nextNode = adj[currNode][i];

            if(dist[nextNode] == 0) {
                dist[nextNode] = dist[currNode] + 1;
                q.push(nextNode);

                if(dist[nextNode] > maxDistance) {
                    maxDistance = dist[nextNode], farthestNode = nextNode;
                }
            }
        }
    }

    return {farthestNode, maxDistance};
}
int _getDiameter(int &rootNode) {
    // Running the first BFS from the root node (as explained in the procedue 1)
    pair<int, int> pii = _bfs(rootNode);

    // Running the second BFS from the furthest node we've found after running first BFS (as explained in the procedure 2)
    pair<int, int> pii2 = _bfs(pii.first);

    return pii2.second;
}
int Solution::solve(vector<int> &A) {
    totalNode = A.size();
    int rootNode;

    if(totalNode == 1) return 0;
    if(totalNode == 2) return 1;

    for(int i = 0; i < totalNode; i++) adj[i].clear();

    for(int i = 0; i < totalNode; i++) {
        int n = A[i];
        if(n == -1) rootNode = i;
        else adj[i].push_back(n), adj[n].push_back(i);
    }

    return _getDiameter(rootNode) - 1;
}

参考:

Diameter of a tree using DFS

Finding Diameter of a Tree using DFS with proof

【讨论】:

  • 你是否建议如果我从任何叶节点开始并运行 BFS/DFS 一次它会为我提供树的直径???
  • @ShubhamSharma 不,您已被明确告知您需要运行两次搜索。
  • @Anonymous668890 我在我的代码中添加了注释。请从头再读一遍程序,然后看代码。根据上述过程,您必须运行 2 个 BFS 或 DFS 才能获得树的直径。
  • 这个:'最长的路径总是出现在两个叶子节点之间。'不正确。
  • ......至少不在被理解为编程中的数据结构的“树”中(有根的 DAG)。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多