Graph 用BFS求一棵树的直径中心?

Graph 用BFS求一棵树的直径中心?,graph,breadth-first-search,Graph,Breadth First Search,所以这个函数,maximum_dist,找到一个图的直径(任务中给定的图总是一棵树) 我想让它找到的是直径的中心,这个节点到所有其他节点的最大距离最小 我“有点”理解这样一种想法,即我们可以通过跟踪每个节点的父节点来找到从u到t的路径(u和t之间的距离是直径),从而做到这一点。在这里,我选择了 u>代码>的中间节点> t>代码>?我的问题是如何在这里实现这个函数?这会使它成为此图的输出节点2吗 int biggest_dist(int n, int v, const vector< ve

所以这个函数,maximum_dist,找到一个图的直径(任务中给定的图总是一棵树)

我想让它找到的是直径的中心,这个节点到所有其他节点的最大距离最小

我“有点”理解这样一种想法,即我们可以通过跟踪每个节点的父节点来找到从
u
t
的路径(
u
t
之间的距离是直径),从而做到这一点。在这里,我选择了<代码> u>代码>的中间节点> <代码> t>代码>?我的问题是如何在这里实现这个函数?这会使它成为此图的输出节点2吗

int biggest_dist(int n, int v, const vector< vector<int> >& graph)
//n are amount of nodes, v is an arbitrary vertex
{ //This function finds the diameter of thegraph
int INF = 2 * graph.size(); // Bigger than any other length
vector<int> dist(n, INF);

dist[v] = 0;
queue<int> next;
next.push(v);

int bdist = 0; //biggest distance
while (!next.empty()) {
    int pos = next.front();
    next.pop();
    bdist = dist[pos];

    for (int i = 0; i < graph[pos].size(); ++i) {
        int nghbr = graph[pos][i];
        if (dist[nghbr] > dist[pos] + 1) {
            dist[nghbr] = dist[pos] + 1;
            next.push(nghbr);
        }
    }
}

return bdist;
}
int最大距离(int n,int v,常量向量&graph)
//n是节点数,v是任意顶点
{//此函数用于查找图形的直径
int INF=2*graph.size();//大于任何其他长度
向量距离(n,INF);
距离[v]=0;
然后排队;
下一步,推(v);
int bdist=0;//最大距离
而(!next.empty()){
int pos=next.front();
next.pop();
bdist=dist[pos];
对于(int i=0;i距离[pos]+1){
距离[nghbr]=距离[pos]+1;
下一步。推送(nghbr);
}
}
}
返回bdist;
}

事实上,此函数不计算直径。它从给定顶点计算最远的顶点
v

要计算一棵树的直径,首先需要选择一个任意顶点(比如说
v
),然后找到距离
v
最远的顶点(比如说
w
),然后找到距离
w
最远的顶点,让我们坐
u
w
u
之间的距离是树的直径,但是
v
w
之间的距离(您的函数正在执行的操作)不能保证是直径

要使函数计算直径,需要使其返回与距离一起找到的顶点。方便的是,它将始终是您处理的最后一个元素,因此只需让您的函数记住它处理的最后一个元素以及到该元素的距离,然后将它们都返回。然后调用函数两次,首先从任意顶点调用,然后从第一次调用返回的顶点调用

为了让它真正找到中心,您还可以在BFS期间记住每个节点的父节点。要执行此操作,请分配一个额外的数组,例如
prev
,并在执行此操作时分配

dist[nghbr]=dist[pos]+1;
也做

prev[nghbr]=pos;
然后,在对函数的第二次调用结束时,您可以将bdist下降/2次到prev,类似于:

center=lastVertex;
对于(inti=0;i+i
因此,对函数稍加调整(使其返回距离
v
最远的顶点,以及位于路径中间的顶点,而不返回直径),此代码可能会返回树的中心(我仅在您的示例中对其进行了测试,因此它可能会出现一些错误)

对最大距离(int n,int v,const vector&graph)
{
int INF=2*graph.size();//大于任何其他长度
向量距离(n,INF);
向量prev(n,INF);
距离[v]=0;
然后排队;
下一步,推(v);
int bdist=0;//最大距离
int lastV=v;
而(!next.empty()){
int pos=next.front();
next.pop();
bdist=dist[pos];
lastV=pos;
对于(int i=0;i距离[pos]+1){
距离[nghbr]=距离[pos]+1;
上一个[nghbr]=位置;
下一步。推送(nghbr);
}
}
}
int center=lastV;
对于(inti=0;i+i&图形)
{
//第一个调用是获取距离顶点0最远的顶点,其中0只是任意顶点
pair firstResult=最大距离(n,0,图形);
//第二个调用是查找距离刚刚找到的顶点最远的顶点
pair secondResult=最大距离(n,firstResult.first,graph);
返回secondResult.second;
}

对于树,您可以使用一个可爱的算法:同时删除图中的所有叶子,并重复此操作,直到剩下一个或两个节点。剩下的节点就是中心。这对你有用吗,还是你特别想使用上面的代码。。。您可以将其视为一个图形,dfs从u到t,然后返回diameter/2次。或者,如果出于某种原因,作为一棵树更方便,您可以在树的根上找到所有深度,然后找到较低节点的第(直径/2)个父节点。。。(我想?)编辑:你的代码是如何找到图形的直径的,它似乎只是找到了距离节点v最远的距离?这正是我想要的答案!谢谢!:-)