树讲解——树的输入,重心,直径
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树讲解——树的输入,重心,直径相关的知识,希望对你有一定的参考价值。
one.树的输入
1.输入每个节点父亲节点的编号
#include<vector> #include<stdio.h> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 100000 #define maxn 123456 using namespace std; int n,x,fa[N]; bool vis[N]; vector<int>vec[N]; void dfs(int x) { vis[x]=1; for(int i=0;i<vec[x].size();i++) dfs(vec[x][i]); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&x); fa[i]=x; vec[x].push_back(i);//由x向i连一条有向边 } dfs(1); }
2.直接输入树上n-1条边,不确定根
#include<vector> #include<stdio.h> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 10000 #define maxn 123456 using namespace std; vector<int>vec[N]; int n,x,y,fa[N]; bool vis[N]; void dfs(int x) { vis[x]=1; for(int i=0;i<vec[x].size();i++) { if(vec[x][i]!=fa[x]) { fa[vec[x][i]]=x; dfs(vec[x][i]); } } } int main() { scanf("%d",&n); for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); vec[x].push_back(y); vec[y].push_back(x); } dfs(1); return 0; }
two。树的直径
树的直径即为在这棵树上最长的简单路径。
做法:
首先,我们先随便找一个点为各节点对整棵树进行一下dfs,求出离这个点最远的节点t
然后,我们在以t点为根节点对整棵树进行一下dfs,求出这个点最远的节点m
这样我们就称tm是这棵树的直径!
求树的直径的代码
#include<vector> #include<stdio.h> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 10000 #define maxn 123456 using namespace std; vector<int>vec[N]; int n,x,y,fa[N],s,t,dis[N]; void dfs(int x) { for(int i=0;i<vec[x].size();i++) { if(!dis[vec[x][i]]) { dis[vec[x][i]]=dis[x]+1; dfs(vec[x][i]); } } } int main() { scanf("%d",&n); for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); vec[x].push_back(y); vec[y].push_back(x); } dis[1]=1; dfs(1); for(int i=t=1;i<=n;i++) if(dis[t]>dis[i]) t=i; memset(dis,0,sizeof(dis)); dis[t]=1; dfs(t); for(int i=s=1;i<=n;i++) if(dis[s]>dis[i]) s=i; printf("%d",dis[s]-1); return 0; }
three。树的重心
找到一个点,若这个点满足他的子树中的最大子节点数最少,那这个点就是树的重心
在树的总点数是偶数的时候,一个树可能有两个重心。
在找树的重心时,随意确定一个根,对整棵树进行一遍dfs,找出每个节点的子节点的个数
一棵树的重心满足他的子节点的个数:2*sizei>=n,但他的子节点2*sizei<=n,那这个点就是树的重心
代码
#include<vector> #include<stdio.h> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 100000 #define maxn 123456 using namespace std; vector<int>vec[N]; int n,x,y,ans,size[N],fa[N]; void dfs(int x) { size[x]=1; for(int i=0;i<vec[x].size();i++) { if(fa[x]!=vec[x][i]) { fa[vec[x][i]]=x; dfs(vec[x][i]); size[x]+=size[vec[x][i]]; } } if(!ans&&size[x]*2>=n) ans=x; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&x,&y); vec[x].push_back(y); vec[y].push_back(x); } dfs(1); printf("%d",ans); return 0; }
就算慢又怎样,一步一个脚印,回头看时,还是有别样的风采!
以上是关于树讲解——树的输入,重心,直径的主要内容,如果未能解决你的问题,请参考以下文章