<题目链接>
题目大意:
求一颗带权树上任意两点的最远路径长度。
解题分析:
裸的树的直径,可由树形DP和DFS、BFS求解,下面介绍的是BFS解法。
在树上跑两遍BFS即可,第一遍BFS以任意点为起点,此时得到的离它距离最远的点为树的直径上的端点之一,然后再以这个端点为起点,跑一遍BFS,此时离它最远的点为树直径的另一个端点,同时,它们之间的距离即为树的直径。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int M=1e4+10; 8 9 struct Edge{ 10 int to,val,next; 11 }edge[M<<1]; 12 int vis[M],d[M]; 13 int head[M],cnt; 14 int res,ans; 15 void init(){ 16 cnt=0; 17 memset(head,-1,sizeof(head)); 18 } 19 void addedge(int u,int v,int w){ 20 edge[++cnt].to=v,edge[cnt].val=w; 21 edge[cnt].next=head[u],head[u]=cnt; 22 } 23 void bfs(int s){ 24 memset(vis,0,sizeof(vis)); 25 queue<int>que; 26 vis[s]=1;d[s]=0; 27 que.push(s); 28 while(!que.empty()){ 29 int u=que.front(); 30 que.pop(); 31 for(int i=head[u]; i!=-1; i=edge[i].next){ 32 int v=edge[i].to; 33 if(!vis[v]){ 34 d[v]=d[u]+edge[i].val; 35 vis[v]=1; 36 que.push(v); 37 if(d[v]>ans) //更新最远距离 38 ans=d[v],res=v; 39 } 40 } 41 } 42 } 43 int main(){ 44 init(); 45 int u,v,w; 46 while(scanf("%d%d%d",&u,&v,&w)!=EOF) 47 addedge(u,v,w),addedge(v,u,w); 48 ans=0; 49 bfs(1); //先得到离1距离最远的节点(该节点为树的直径那两个节点之一) 50 bfs(res); //然后再跑一遍BFS,得到直径的另一个端点 51 printf("%d ",ans); 52 return 0; 53 }
2018-11-07