找到无向树中最长的路径

时间:2015-06-04 06:50:04

标签: c++ algorithm tree depth-first-search

我试图在无向树中找到最长的路径(http://www.spoj.com/problems/PT07Z/)并制作以下​​代码。

#include <iostream>
#include <vector>

using namespace std;

vector< vector<int> > graph;
int q=0, m = -1;                                // m is for largest path and q is one of the end vertex of that path

void dfs(int i, int count, vector<bool>& v)
{
    v[i] = true;
    for(int j=0;j<graph[i].size();j++)
    {
        if(!v[graph[i][j]])
        {
            count++;                            // count is the length of the path from the starting vertex to current vertex
            dfs(graph[i][j], count, v);
        }
    }
    if(count>m)
    {
        m= count;
        q=i;
    }
    count--;                                    // decreasing count since the method return to its calling function
}


int main()
{
    int n, x, i, y;
    cin>>n;
    graph = vector< vector<int> >(n);
    vector<bool> visited(n);
    vector<bool> v(n);
    for(i=0;i<n-1;i++)
    {
        cin>>x>>y;
        x--, y--;
        graph[x].push_back(y);
        graph[y].push_back(x);
    }
    dfs(0, 0, visited);
    m=-1;
    cout<<q<<endl;
    dfs(q, 0, v);
    cout<<q<<endl;
    cout<<m<<endl;
}

任何人都可以告诉我这里有什么问题,因为尽管最长路径的末端顶点是正确的(我尝试过的测试用例至少),但我得到的路径最大长度值(m)也是错误的。我试图在这里实现以下算法:

算法:

  1. 从任何节点运行DFS以查找最远的叶节点。标记节点T。
  2. 运行另一个DFS以从T找到最远的节点。
  3. 您在步骤2中找到的路径是树中最长的路径。
  4. 一些测试用例: 第一:

    17
    1 2
    1 3
    2 4
    2 5
    3 6
    3 7
    6 8
    6 9
    8 10
    9 11
    7 12
    7 13
    13 14
    13 15
    15 16
    15 17
    

    此测试用例的正确答案是7。

    第二

    7
    1 2
    1 3
    2 4
    2 5
    3 6
    3 7
    

    此测试用例的正确答案为4。

2 个答案:

答案 0 :(得分:3)

根据我的一个问题是你应该在从被调用的递归函数返回时立即递减计数。

    for(int j=0;j<graph[i].size();j++)
    {
        if(!v[graph[i][j]])
        {
            count++;                           
            dfs(graph[i][j], count, v);
            count--;
        }

或者简单地说:

    for(int j=0;j<graph[i].size();j++)
    {
        if(!v[graph[i][j]])           
            dfs(graph[i][j], count+1, v);

这是因为graph[i]的每个邻居的计数不应该递增。

答案 1 :(得分:1)

从'for'循环中删除该count ++并删除该计数 - ;

并在开始时保持'count ++'。

void dfs(int i, int count, vector<bool>& v)
{
    count++;
    v[i] = true;
    for(int j=0;j<graph[i].size();j++)
    {
       if(!v[graph[i][j]])
        {
            dfs(graph[i][j], count, v);
        }
    }
    if(count>m)
    {
        m= count;
        q=i;
    } 
}