<学习笔记> 树的直径 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 最长链

时间: 2024-11-10 16:59:01

<学习笔记> 树的直径 Bfs、Dfs的相关文章

poj2631 树的直径 + bfs

1 //Accepted 492 KB 0 ms 2 //树的直径 bfs 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 #include <queue> 7 using namespace std; 8 const int imax_n = 10005; 9 struct node 10 { 11 int u,v,c; 12 node() 13 { 14 15 } 16 n

大臣的旅费---树的直径(dfs)

很久以前,T王国空前繁荣.为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市. 为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达. 同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的. J是T国重要大臣,他巡查于各大城市之间,体察民情. 所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情.他有一个钱袋,用于存放往来城市间的路费. 聪明的J发现,如果不在某个城市停下来修整,在连续行进过

hdu2196 树的直径 + bfs

1 //Accepted 740 KB 15 ms 2 //树的直径 3 //距离一个顶点最远的点一定是树的直径的一个端点 4 #include <cstdio> 5 #include <cstring> 6 #include <queue> 7 #include <iostream> 8 using namespace std; 9 const int imax_n = 10005; 10 int dis[imax_n]; 11 int d1[imax_n

算法笔记--树的直径模板

思路: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c之间的距离就是树的直径. 模板: const int N=1e6+5; int head[N]; int dis[N]; bool vis[N]; int cnt=0,b,mxn=0; struct edge { int to,w,next; }edge[N]; void add_edge(int u,

ZOJ 3820 Building Fire Stations 求中点+树的直径+BFS

题意:给一棵树,要求找出两个点,使得所有点到这两个点中距离与自己较近的一个点的距离的最大值(所有点的结果取最大的值,即最远距离)最小. 意思应该都能明白. 解法:考虑将这棵树摆直如下: 那么我们可以把最中间的那条直径边删掉,然后在分成的两颗子树内求一个直径中心点,那么这两个点就可以作为答案. 反正当时就觉得这样是正确的, 但是不能证明. 于是,几个bfs就可以搞定了. 当时写TLE了,原因是存要删的边我用了map<pair<int,int>,int>, 后来改掉就不T了,map这种

[学习笔记]树链剖分

基本思想 树链剖分一种对树进行划分的算法,它先通过轻重边剖分将树分为多条链,保证每条边属于且只属于一条链,然后再通过数据结构来维护每一条链. 一些定义 树链:树上的路径. 剖分:把路径分类为重链和轻链. 重儿子:u的子节点中siz[v]值最大的v. 轻儿子:u的其它子节点. 重边:点u与其重儿子的连边. 轻边:点u与其轻儿子的连边. 重链:由重边连成的路径. 轻链:轻边. 性质 如果(u,v)为轻边,则siz[v]$\times$2<siz[u]. 从根到某一点的路径上轻链.重链的个数都不大于l

基本数据结构学习笔记——树与二叉树

1.树的形式化定义: 树(Tree)是由一个或多个结点组成的有限集合T,其中有一个特定的称为根的结点:其余结点可分为m(m≥0)个互不相交的有限集T1,T2,T3 ,…,Tm,每一个集合本身又是一棵树,且称为根的子树. 2.有关树的基本术语: 1.结点(Node):树中的元素,包含数据项及若干指向其子树的分支. 2.结点的度(Degree):结点拥有的子树数. 3.结点的层次:从根结点开始算起,根为第一层. 4.叶子(Leaf):度为零的结点,也称端结点. 5.孩子(Child):结点子树的根称

【算法学习笔记】61.回溯法 DFS SJTU OJ 1106 sudoku

虽然DLX可以提高效率....但是对于NPC问题也不用太追求效率了,而且还只有一个测试点. 所以 只要DFS不断的填入,直到空格全部被填满:要注意的是DFS中全局变量的更新和恢复. 至于存储的方法,只要考虑每一行每一列每一个小块的不重复即可. #include <iostream> #include <cstring> using namespace std; int cnt = 0 ;//表示剩余的要填的空格的数目 struct point { int x,y; }; point

Java-J2SE学习笔记-树状展现文件结构

1.利用java.io相关类树状展现文件结构 2.判定给定路径是否为dir,是则递归,每一递归一层缩进一次 3.代码 package Test; import java.io.File; public class TestHierarchical { public static void main(String[] args) { File file = new File("D:/Workspaces/eclipse/test"); tree(file, 0); } private s