Luogu P4006 小 Y 和二叉树

题目
我们知道,答案序列的第一个数一定是最小的度数不为(3)的点,记为(x)
我们以(x)为根先(dfs)一遍,预处理出每个点的子树中最小的度数不为(3)的点的编号(f)
我们知道(x)是答案的第一位,所以(x)一定在真正的二叉树的根的左下的最远处。
所以我们再从(x)开始从左下往右上(dfs)
假设我们当前(dfs)到的点是(u),我们分几种情况:
1、(deg_u=1)
搞笑吧.
2、(deg_u=2)
假设唯一的出点为(v)
如果(f_v<v),那么最优的方案为把(v)接在(u)的右儿子上,(u)就是这棵树的实际的根。
如果(f_v=v),搞笑吧。
如果(f_v>v),那么最优的方案为让(v)(u)的父亲。
3、(deg_u=3)
设出点为(ls,rs(f_{ls}<f_{rs}))
此时最优的方案显然是把(ls)接在(u)的右儿子上,让(ls)(u)的父亲。
上面就是所有的情况。
如果我们让(v)做了(u)的父亲,那么我们继续从(v)(dfs)
如果我们让(v)做了(u)的右儿子,那么我们用另一个(dfs)来做以(v)为根的子树最小中序遍历。

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
namespace IO
{
    char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[15],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
    char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
    void Flush(){fwrite(obuf,1,oS-obuf,stdout),oS=obuf;}
    void Put(char x){*oS++=x;if(oS==oT)Flush();}
    int read(){int x=0;char ch=Get();while(ch>57||ch<48)ch=Get();while(ch>=48&&ch<=57)x=x*10+(ch^48),ch=Get();return x;}
    void write(int x){int top=0;while(x)st[++top]=(x%10)+48,x/=10;while(top)Put(st[top--]);Put(' ');}
}
using namespace IO;
void swap(int &a,int &b){a^=b^=a^=b;}
const int N=1000007,inf=1e9;
vector<int>E[N];
int n,rt,cnt,deg[N],ans[N],f[N],id[N];
void dfs(int u,int fa)
{
    f[u]=(deg[u]^3? u:inf),id[u]=u;
    for(int v:E[u])  if(v^fa) dfs(v,u),f[v]<f[u]? f[u]=f[v],id[u]=v:0;
}
void dfs1(int u,int fa)
{
    if(id[u]^u) dfs1(id[u],u);ans[++cnt]=u;
    for(int v:E[u]) if(v^id[u]&&v^fa) dfs1(v,u);
}
void dfs2(int u,int fa) 
{
    ans[++cnt]=u;
    if(deg[u]==1) return;
    int ls=0,rs=0;
    for(int v:E[u])
    {
	if(v==fa) continue;
	if(deg[u]==2) return v<f[v]? dfs2(v,u):dfs1(v,u);
	ls? rs=v:ls=v;
    }
    if(f[ls]>f[rs]) swap(ls,rs);
    dfs1(ls,u),dfs2(rs,u);
}
int main()
{
    n=read();int i,j;
    for(i=1;i<=n;++i)
    {
	for(deg[i]=read(),j=1;j<=deg[i];++j) E[i].pb(read());
	if(deg[i]<3&&!rt) rt=i;
    }
    dfs(rt,0),++deg[rt],dfs2(rt,0);
    for(i=1;i<=n;++i) write(ans[i]);
    return Flush(),0;
}
原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11600172.html