<学习笔记> 树的直径 Bfs、Dfs
树的直径为树上最长的一条路径(不经过重复节点),也可以看做是树上最长路。
通常的求法:
1.两边Bfs或两边Dfs
2.树形dp(端点为根和仅经过根)。
emmm 。。蒟蒻表示目前只会第一种QAQ。
从树中找出任意一点,求出与他距离最远的点s,再用同样的方法求出与s距离最远的点t,s-t即为树的直径。
Bfs代码
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 using namespace std; 7 8 int N,l,r,cnt,pos,ans; 9 int first[100010],next[200010]; 10 int q[100010],de[100010]; 11 bool used[100010]; 12 13 struct maple{ 14 int f,t; 15 }Rode[200010]; 16 17 void Build(int f,int t) 18 { 19 Rode[++cnt]=(maple){f,t}; 20 next[cnt]=first[f]; 21 first[f]=cnt; 22 } 23 void Bfs(int k) 24 { 25 memset(used,0,sizeof(used)); 26 memset(de,0,sizeof(de)); 27 int head=0,tail=1; 28 used[k]=1; 29 q[tail]=k; 30 while(head<tail) 31 { 32 ++head; 33 int a=q[head]; 34 for(int i=first[a];i;i=next[i]) 35 if(!used[Rode[i].t]) 36 { 37 used[Rode[i].t]=1; 38 de[Rode[i].t]=de[a]+1; 39 q[++tail]=Rode[i].t; 40 } 41 } 42 pos=q[head] ; ans=de[pos]; 43 } 44 45 int main() 46 { 47 scanf("%d",&N); 48 for(int i=1;i<=N;++i) 49 { 50 scanf("%d%d",&l,&r); 51 if(l) Build(i,l),Build(l,i); 52 if(r) Build(i,r),Build(r,i); 53 } 54 Bfs(1); 55 Bfs(pos); 56 printf("%d",ans); 57 return 0; 58 }
Dfs 代码
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 using namespace std; 7 8 int N,l,r,cnt,pos,ans; 9 int first[100010],next[200010]; 10 11 struct maple{ 12 int f,t; 13 }Rode[200010]; 14 15 void Build(int f,int t) 16 { 17 Rode[++cnt]=(maple){f,t}; 18 next[cnt]=first[f]; 19 first[f]=cnt; 20 } 21 void Dfs(int k,int dis,int fa) 22 { 23 if(dis>ans) ans=dis,pos=k; 24 for(int i=first[k];i;i=next[i]) 25 if(Rode[i].t!=fa) 26 Dfs(Rode[i].t,dis+1,k); 27 } 28 29 int main() 30 { 31 scanf("%d",&N); 32 for(int i=1;i<=N;++i) 33 { 34 scanf("%d%d",&l,&r); 35 if(l) Build(i,l),Build(l,i); 36 if(r) Build(i,r),Build(r,i); 37 } 38 Dfs(1,0,-1); 39 Dfs(pos,0,-1); 40 printf("%d",ans); 41 return 0; 42 }
例题:codevs 1814 最长链