樹講解(2)——樹的輸入,重心,直徑
阿新 • • 發佈:2017-05-07
str 樹的直徑 names n) ostream push main define span
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(intx) { 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; }
就算慢又怎樣,一步一個腳印,回頭看時,還是有別樣的風采!
樹講解(2)——樹的輸入,重心,直徑