树的直径

树形dp:

可以知道从一个点出发,他的最长边加上次长边就是直径。

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <vector>
 4 using namespace std;
 5 const int N=1e5+10;
 6 vector<pair<int,int > >arr[N];
 7 int ans=0;
 8 int dfs(int x,int px){
 9     int d1=0,d2=0,d;
10     for(int i=0;i<arr[x].size();i++){
11         if(arr[x][i].first==px)
12             continue;
13         d=dfs(arr[x][i].first,x)+arr[x][i].second;
14         if(d>d1){
15             d2=d1;
16             d1=d;
17         }
18         else if(d>d2){
19             d2=d;
20         }
21     }
22     ans=max(ans,d1+d2);
23     return d1;
24 }
25 
26 int main(){
27     int n,m,a,b,d;
28     char c;
29     cin>>n>>m;
30     for(int i=0;i<m;i++){
31         scanf("%d %d %d %c",&a,&b,&d,&c);
32         arr[a].push_back({b,d});
33         arr[b].push_back({a,d});
34     }
35     dfs(1,-1);
36     cout<<ans<<endl;
37     return 0;
38 } 

 

两遍dfs&bfs:

先从任意一点出发找到最长的边,在从最长的边出发找到这条最长的边的另一个端点,那么这个最长的边就是直径。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2e5+10;
 4 vector<int> arr[maxn];
 5 int n,vis[maxn],dis[maxn],pos,flag;
 6 void bfs(int x){
 7     memset(vis,0,sizeof(vis));
 8     memset(dis,0,sizeof(dis));
 9     pos=x;
10     vis[x]=1,dis[x]=0;
11     queue<int> q;
12     q.push(x);
13     while(!q.empty()){
14         int u=q.front();q.pop();
15         for(int i=0;i<arr[u].size();i++){
16             if(!vis[arr[u][i]]){
17                 vis[arr[u][i]]=1;
18                 dis[arr[u][i]]=dis[u]+1;
19                 q.push(arr[u][i]);
20                 if(dis[arr[u][i]]>dis[pos]) pos=arr[u][i];
21             }
22         }
23     }
24 }
25 void dfs_path(int x){
26     if(flag==1){
27         return ;
28     }
29     else if(vis[x]==0){
30         flag=1;
31         return ;
32     }
33     else{
34         for(int i=0;i<arr[x].size();i++){
35             if(dis[arr[x][i]]==dis[x]-1){
36                 cout<<arr[x][i]<<" ";
37                 dfs_path(arr[x][i]);
38             }
39             if(flag){
40                 return ;
41             }
42         }
43     }
44 }
45 int main(){
46     int u,v,a,b;
47     scanf("%d",&n);
48     for(int i=1;i<n;i++){
49         scanf("%d%d",&u,&v);
50         arr[u].push_back(v);
51         arr[v].push_back(u);
52     }
53     bfs(1);
54     a=pos;
55     bfs(pos);
56     b=pos,flag=0;
57     cout<<b<<" ";//直径路径 
58     dfs_path(b);
59     cout<<endl;
60     cout<<dis[b]<<" "<<a<<" "<<b;//直径长度及起点和终点 
61     return 0;
62 }

 

 

posted @ 2019-10-29 15:27  yya雨  阅读(90)  评论(0编辑  收藏  举报