C++ 查找从节点到最远节点的距离

C++ 查找从节点到最远节点的距离,c++,boost,c++11,nodes,longest-path,C++,Boost,C++11,Nodes,Longest Path,我需要在最小生成树中确定从所有节点到距离它最远的节点的距离。到目前为止,我已经这样做了,但是我没有找到从节点到节点的最长距离的线索 #include<iostream> #include<boost/config.hpp> #include<boost/graph/adjacency_list.hpp> #include<boost/graph/kruskal_min_spanning_tree.hpp> #include<boost/gra

我需要在最小生成树中确定从所有节点到距离它最远的节点的距离。到目前为止,我已经这样做了,但是我没有找到从节点到节点的最长距离的线索

#include<iostream>
#include<boost/config.hpp>
#include<boost/graph/adjacency_list.hpp>
#include<boost/graph/kruskal_min_spanning_tree.hpp>
#include<boost/graph/prim_minimum_spanning_tree.hpp>

using namespace std;
using namespace boost;

int main()
{
typedef adjacency_list< vecS, vecS, undirectedS, property <vertex_distance_t,int>, property< edge_weight_t, int> > Graph;
int test=0,m,a,b,c,w,d,i,no_v,no_e,arr_w[100],arr_d[100];
cin>>test;
m=0;
while(m!=test)
{
cin>>no_v>>no_e;
Graph g(no_v);
property_map <Graph, edge_weight_t>:: type weightMap=get(edge_weight,g);
bool bol;
graph_traits<Graph>::edge_descriptor ed;

for(i=0;i<no_e;i++)
{
cin>>a>>b>>c;
tie(ed,bol)=add_edge(a,b,g);
weightMap[ed]=c;
}

property_map<Graph,edge_weight_t>::type weightM=get(edge_weight,g);
property_map<Graph,vertex_distance_t>::type distanceMap=get(vertex_distance,g);
property_map<Graph,vertex_index_t>::type indexMap=get(vertex_index,g);

vector< graph_traits<Graph>::edge_descriptor> spanning_tree;

kruskal_minimum_spanning_tree(g,back_inserter(spanning_tree));

vector<graph_traits<Graph>::vector_descriptor>p(no_v);

prim_minimum_spanning_tree(g,0,&p[0],distancemap,weightMap,indexMap,default_dijkstra_visitor());



w=0;

for(vector<graph_traits<Graph>::edge_descriptor>::iterator eb=spanning_tree.begin();eb!=spanning_tree.end();++eb) //spanning tree weight
{
w=w+weightM[*eb];
}

arr_w[m]=w;
d=0;

graph_traits<Graph>::vertex_iterator vb,ve;

for(tie(vb,ve)=vertices(g),.

arr_d[m]=d;
m++;
}

for( i=0;i<test;i++)
{
cout<<arr_w[i]<<endl;
}

return 0;
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
使用名称空间boost;
int main()
{
typedef邻接列表>图形;
int test=0,m,a,b,c,w,d,i,no_v,no_e,arr_w[100],arr_d[100];
cin>>试验;
m=0;
while(m!=测试)
{
cin>>否v>>否e;
图g(no_v);
属性映射::类型weightMap=get(边权重,g);
布尔布尔;
图特征::边描述符ed;
对于(i=0;i>a>>b>>c;
连接(ed,bol)=添加边(a,b,g);
加权映射[ed]=c;
}
属性映射::类型weightM=get(边权重,g);
属性映射::类型distanceMap=get(顶点映射距离,g);
属性映射::类型indexMap=get(顶点索引,g);
向量生成树;
kruskal_最小生成树(g,back_插入器(生成树));
向量(no_v);
基本最小生成树(g,0,&p[0],距离映射,权重映射,索引映射,默认dijkstra_visitor());
w=0;
for(vector::iterator eb=生成树.begin();eb!=生成树.end();++eb)//生成树权重
{
w=w+权重M[*eb];
}
arr_w[m]=w;
d=0;
图特征:顶点迭代器vb,ve;
对于(tie(vb,ve)=顶点(g),。
arr_d[m]=d;
m++;
}

对于(i=0;i我不会给你具体的代码,但是我会给你一些想法和方法

首先,MST(最小生成树)的结果被称为树。考虑一下定义。可以说它是一个图,其中存在从每个节点到每个其他节点的路径,并且没有循环。或者,您可以说给定的图是一个树,iff对于每个u和v恰好存在一条从顶点u到v的路径

根据定义,您可以定义以下内容

function DFS_Farthest (Vertex u, Vertices P)
begin
    define farthest is 0
    define P0 as empty set
    add u to P

    foreach v from neighbours of u and v is not in P do
    begin
        ( len, Ps ) = DFS_Farthest(v, P)
        if L(u, v) + len > farthest then
        begin
            P0 is Ps union P
            farthest is len + L(u, v)
        end
    end

    return (farthest, P0)
end
然后,您将为图形调用中的每个顶点v
DFS\u Farthest(v,空集)
提供(Farthest,p),其中Farthest是最远节点的距离,p是顶点集,您可以从中重建从v到最远顶点的路径

现在来描述它在做什么。首先是签名。第一个参数是你想知道的最远的顶点。第二个参数是一组被禁止的顶点。所以它说“嘿,给我从v到最远顶点的最长路径,这样p的顶点就不在该路径中”

接下来是这个
foreach
的东西。在这里,您正在寻找距离当前顶点最远的顶点,而不访问p中已经存在的顶点(当前顶点已经存在)。当您找到比当前找到的路径更长的路径时,它将到达
foreach
P0
。请注意
L(u,v)
是边的长度{u,v}

最后,您将返回这些长度和禁用顶点(这是到最远顶点的路径)

这只是一个简单的DFS(深度优先搜索)算法,您可以记住已经访问过的顶点

现在谈谈时间复杂性。假设你能在O(1)中得到给定顶点的邻域(取决于你的数据结构)。函数只访问每个顶点一次。所以它至少是O(N)。若要知道距离每个顶点最远的顶点,您必须为每个顶点调用此函数。这使您的问题的此解决方案的时间复杂性至少为O(n^2)


我的猜测是,更好的解决方案可能使用动态规划,但这只是一个猜测。通常,在图中查找最长路径是NP难问题。这使我怀疑可能没有更好的解决方案。但这是另一个猜测。

时间复杂度如何。是O(n^2)足够好吗?因为朴素的解决方案就这么好。我还没有想出任何办法。所以我认为对于初学者来说,朴素的解决方案会很好,甚至很难。我一直在努力找到一个更聪明的解决方案。