PAT【41/155】
树
1020 Tree Traversals
巧妙:用map存左孩子、右孩子、在中序遍历的下标位置
层序遍历=bfs,用数组即可完成
#include<iostream>
#include<unordered_map>
#include<algorithm>
using namespace std;
#define MaxN 40
int postorder[MaxN],inorder[MaxN];
unordered_map<int,int> l,r,pos;
int q[MaxN];
int N;
int build(int il,int ir,int pl,int pr){
int root=postorder[pr];
int k=pos[root];
if(il<k){//有左孩子
l[root]=build(il,k-1,pl,pl+(k-1-il));
}
if(k<ir){//有右孩子
r[root]=build(k+1,ir,pl+(k-1-il)+1,pr-1);
}
return root;
}
void bfs(int root){
int hh=0,tt=0;
q[0]=root;
while(hh<=tt){
int t=q[hh++];
if(l.count(t)){
q[++tt]=l[t];
}
if(r.count(t)){
q[++tt]=r[t];
}
}
cout<<q[0];
for(int i=1;i<N;i++){
cout<<" "<<q[i];
}
cout<<endl;
}
int main(){
scanf("%d",&N);
for(int i=0;i<N;i++)scanf("%d",&postorder[i]);
for(int i=0;i<N;i++){
scanf("%d",&inorder[i]);
pos[inorder[i]]=i;
}
int root=build(0,N-1,0,N-1);
bfs(root);//层序遍历
return 0;
}
1021 Deepest Root
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
#define MaxN 10010
const int MaxM=MaxN*2;//因为是无向图,存两次双向边
int p[MaxN];//并查集
int h[MaxN],E[MaxM],ne[MaxM],idx;//add edge
int N;
int find(int x){
if(p[x]!=x){
p[x]=find(p[x]);
}
return p[x];
}
void add(int a,int b){
E[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
int dfs(int son,int father){
int depth=0;
for(int i=h[son];i!=-1;i=ne[i]){
if(E[i]==father)continue;
depth=max(depth,dfs(E[i],son)+1);
}
return depth;
}
int main(){
cin>>N;
memset(h,-1,sizeof h);//h记录儿子
for(int i=1;i<=N;i++){
p[i]=i;
}
int k=N;//联通分量
for(int i=0;i<N-1;i++){
int a,b;
cin>>a>>b;
if(find(a)!=find(b)){
p[find(a)]=find(b);
k--;
}
add(a,b);
add(b,a);
}
if(k>1){
printf("Error: %d components\n",k);
}else{
vector<int> nodes;
int max_depth=-1;
for(int i=1;i<=N;i++){
int depth=dfs(i,-1);
if(depth>max_depth){
max_depth=depth;
nodes.clear();
nodes.push_back(i);
}else if(depth==max_depth){
nodes.push_back(i);
}
}
for(auto v:nodes){
cout<<v<<endl;
}
}
return 0;
}