题目给出了一个有权无向树T,要求出这棵树的直径(找出相距最远的两个点的距离)
思路:
1.先任取一个点s,先求出T中到s距离最远的点x;
2.再求出T中到点x距离最远的点y,这就是题目所要求的直径距离。
具体证明略,感性的理解就是,通过第一步为了找出一个附近权值比较大的叶子节点作为开始点,然后找到距离开始点最远的点,距离就是该树的直径。
主要实现的部分是在【给出一个点x,求出在树T中,距离x最远的节点y】
基本的想法是,以x作为起点,然后bfs去遍历这棵树,记录下每个点的距离,最后找出最大距离。
代码实现如下:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
using namespace std;
const int maxx=100010;
vector<pair<int,int > > A[maxx];
int d[maxx];
bool flag[maxx];
int n,a,s,b,ans=0;
int bfs(int u){
int cur;
queue<int> S;
S.push(u);
d[u]=0;
while(S.empty()==0){
cur=S.front();
S.pop();
flag[cur]=true;
for(int i=0;i<A[cur].size();i++){
if(flag[A[cur][i].first]==false){
d[A[cur][i].first]=d[cur]+A[cur][i].second;
S.push(A[cur][i].first);
}
}
}
int m=d[u];
cur=u;
for(int i=0;i<n;i++) {
if(d[i]>m){
m=d[i];
cur=i;
}
}
ans=d[cur];
return cur;
}
int main(){
std::ios::sync_with_stdio(false);
for(int i=0;i<maxx;i++){
flag[i]=false;
}
cin>>n;
int x,y,v;
for(int i=1;i<n;i++){
cin>>x>>y>>v;
A[x].push_back(make_pair(y,v));
A[y].push_back(make_pair(x,v));
}
a=0;
s=bfs(a);
for(int i=0;i<maxx;i++){
flag[i]=false;
}
b=bfs(s);
cout<<ans<<endl;
return 0;
}
错点:
1.在执行第二步之前要初始化flag数组;
2.在找出距离最大的节点时,还是要遍历去寻找距离最远的节点,不可以直接使用cur的最后一个值,因为cur的最后一个值只是bfs最后搜索的点,并不一定是距离最远的点;
3.读入时因为是无向图,要双向加边!!!总是会忘。。。