树的直径
树形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 }