[英]Problem in finding the diameter of a tree using depth-first search
我正在编写用于查找树的最大成本直径的代码。 我正在使用深度优先技术,在该技术中我找到离节点最远的节点(可以是根节点),然后找到离该节点最远的节点。
例如,如果输入如下所示:
8
7
1 2 5
2 7 6
2 4 2
4 5 1
4 3 9
1 8 3
8 6 4
其中第一行包含节点数,第二行提到树中没有更新。接下来的 n 行包含两个节点和连接它们的路径的权重。
相应的输出应该是:
6
23
这是我的代码:
#include <iostream>
#include<limits.h>
#include<list>
using namespace std;
int x;
int weight=0;
void dfsutil(int node, int n, int count, int **adj, int &maxcount, bool visited[])
{
visited[node]=true;
count++;
for( auto i=0; i<n; i++)
{
if(!visited[i] && adj[node][i]!=0)
{
if(count>=maxcount)
{
maxcount=count;
weight+=adj[node][i];
x=i;
}
dfsutil(i,n, count, adj, maxcount, visited);
}
}
}
void dfs(int node, int n, int** adj, int &maxcount)
{
bool visited[n+1];
int count=0;
int i;
for(i=1;i<=n;i++)
visited[i]=false;
dfsutil(node, n, count+1, adj, maxcount, visited);
}
int diameter(int n, int **adj)
{
int maxcount;
maxcount=INT_MIN;
dfs(1,n,adj,maxcount);
dfs(x,n,adj,maxcount);
return maxcount;
}
int main()
{
int n,q,i,q1,q2,w;
cout<<"Enter the number of nodes in the tree"<<endl;
cin>>n;
cout<<"Enter the number of queries"<<endl;
cin>>q;
int **adj=new int *[n];
for(i=0;i<n;i++)
{
adj[i]=new int[n];
}
for(i=1;i<=q;i++)
{
cin>>q1>>q2>>w;
adj[q1-1][q2-1]=w;
adj[q2-1][q1-1]=w;
}
cout<<"The diameter is "<<diameter(n,adj)<<endl;
return 0;
}
这段代码存在两个问题:
i) 输出应该是 6 而我得到 4。我找不到什么问题。
ii) 如果两个或多个叶节点处于同一级别但具有不同的权重,则最大成本直径应选择总权重最大的路径。 例如这里,对于权重为9
和1
的4->3
和4->5
,计算直径时可以考虑路径中的任何一个,但在计算成本时,权重为9
的路径即4->3
应选择4->3
。 如何检查这种情况?
在检查你的代码后,我发现了几个错误。 例如,您的dfsUtil
实现不正确。 由于它是一棵加权树,因此您应该根据边权重进行比较,而不是计算节点数。 你的索引也是一团糟。 一致地使用基于0
的索引或基于1
的索引。 混合使用其中的两个会使调试变得更加困难。 最后,您要向函数传递大量信息。 您应该将这些信息封装在一个class
。 它使您的生活变得更加轻松。 以下是我对您要实现的目标的看法:
#include <iostream>
#include <vector>
class Edge{
public:
int node,weight;
Edge() = default;
Edge(int n, int w) : node(n), weight(w) {}
};
class TreeDiameterInfo{
public:
int endPointA, endPointB, diameter;
TreeDiameterInfo() = default;
TreeDiameterInfo(int eA, int eB, int d) : endPointA(eA), endPointB(eB), diameter(d){}
};
class Graph{
static constexpr int MAX_NODE = 100;
int nodes,edges;
std::vector <Edge> adjList[MAX_NODE + 5];
std::vector <int> visited;
std::vector <int> distance;
public:
Graph() = default;
void addEdge(int nodeA, int nodeB,int weight){
adjList[nodeA].emplace_back(Edge(nodeB,weight));
adjList[nodeB].emplace_back(Edge(nodeA,weight));
}
void takeInput(){
std::cin >> nodes >> edges;
for(int i = 0 ; i < edges ; ++i){
int endA,endB,weight;
std::cin >> endA >> endB >> weight;
addEdge(endA,endB,weight);
}
}
void printGraph(){
std::cout << "===== Printing Graph =====\n";
for(int i = 1 ; i <= nodes ; ++i){
std::cout << "Node " << i << ": ";
for(int j = 0 ; j < adjList[i].size() ; j++){
std::cout << "(" << adjList[i][j].node << "," << adjList[i][j].weight << ")";
if(j != adjList[i].size() - 1) std::cout << " ";
}
std::cout << "\n";
}
}
void dfs(int source, int &bestDistance, int &bestNode){
visited[source] = 1;
for(int i = 0 ; i < adjList[source].size() ; ++i){
int adjacentNode = adjList[source][i].node;
int costToNode = adjList[source][i].weight;
if(!visited[adjacentNode]){
distance[adjacentNode] = distance[source] + costToNode;
if(bestDistance < distance[adjacentNode]){
bestDistance = distance[adjacentNode];
bestNode = adjacentNode;
}
dfs(adjacentNode, bestDistance, bestNode);
}
}
}
void initialize(){
visited = std::vector <int> (MAX_NODE + 5, 0) ;
distance = std::vector <int> (MAX_NODE + 5, 0) ;
}
TreeDiameterInfo treeDiameter(){
int farthestNodeFromRoot = -1, distanceFromRoot = -1;
initialize();
dfs(1, distanceFromRoot, farthestNodeFromRoot);
int farthestNodeFromDiameterEndPoint = -1, farthestDistanceFromDiameterEndPoint = -1;
initialize();
dfs(farthestNodeFromRoot, farthestDistanceFromDiameterEndPoint, farthestNodeFromDiameterEndPoint);
return TreeDiameterInfo(farthestNodeFromRoot, farthestNodeFromDiameterEndPoint, farthestDistanceFromDiameterEndPoint);
}
};
int main(){
Graph g;
g.takeInput();
g.printGraph();
TreeDiameterInfo treeDiameterInfo = g.treeDiameter();
std::cout << "Tree Diameter: " << treeDiameterInfo.diameter << "\n";
std::cout << "Two end points of tree diameter: " << treeDiameterInfo.endPointA << " " << treeDiameterInfo.endPointB << "\n";
return 0;
}
输出:
===== Printing Graph =====
Node 1: (2,5) (8,3)
Node 2: (1,5) (7,6) (4,2)
Node 3: (4,9)
Node 4: (2,2) (5,1) (3,9)
Node 5: (4,1)
Node 6: (8,4)
Node 7: (2,6)
Node 8: (1,3) (6,4)
Tree Diameter: 23
Two end points of tree diameter: 3 6
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.