zoukankan      html  css  js  c++  java
  • uoj#339. 【清华集训2017】小 Y 和二叉树(构造)

    传送门

    膜拜大米饼巨巨

    构造思路太神仙了……

    先考虑这个序列的开头,肯定是一个度数小于等于(2)且标号最小的节点,设为(u)

    如果一个点度数小于等于(2),我们称这个点可以被选择,一个点的(mn)为它的子树中(不包括子树的根)能被选择的点中最小的标号

    那么如果能够确定根节点,只要从根节点往下(dfs),然后每次贪心的选择(mn)小的那个节点就好了

    为了找到根节点,我们从(u)开始往下(dfs),先预处理出以(u)为根时所有节点的(mn),那么每一次往下走的时候,只要判断一下走了之后会不会使中序遍历变得更劣,如果不会的话往下走,否则就停在这里,这个就是根节点了

    然后从根节点贪心(dfs)一遍就可以得出答案了

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
    #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    char sr[1<<21],z[20];int C=-1,Z=0;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    void print(R int x){
        if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++C]=z[Z],--Z);sr[++C]=' ';
    }
    const int N=1e6+5;
    struct eg{int v,nx;}e[N<<1];int head[N],tot;
    inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
    int mn[N],ls[N],rs[N],ch[N][2],deg[N];
    int n,st,rt,u,v;
    void dfs1(int u,int fa){
    	int cnt=0;
    	go(u)if(v!=fa){
    		ch[u][cnt++]=v,dfs1(v,u);
    		cmin(mn[u],mn[v]);
    	}
    }
    void dfs2(int u){
    	if(!ch[u][0])return rt=u,void();
    	if(!ch[u][1]){
    		if(ch[u][0]<mn[ch[u][0]])dfs2(ch[u][0]);
    		else return rt=u,void();
    	}else dfs2(mn[ch[u][0]]<mn[ch[u][1]]?ch[u][1]:ch[u][0]);
    }
    int dfs3(int u,int fa){
    	if(deg[u]==1&&u!=rt)return u;
    	int res=n+1,now;if(u==rt&&deg[u]==1||u!=rt&&deg[u]==2)res=u;
    	go(u)if(v!=fa){
    		now=dfs3(v,u);
    		if(now<res)rs[u]=ls[u],ls[u]=v,res=now;
    		else rs[u]=v;
    	}return res;
    }
    void dfs4(int u){
    	if(ls[u])dfs4(ls[u]);
    	print(u);
    	if(rs[u])dfs4(rs[u]);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),st=n+1;
    	fp(i,1,n){
    		deg[i]=read(),mn[i]=n+1;
    		fp(j,1,deg[i])u=read(),add(i,u);
    		if(deg[i]<=2)mn[i]=i,cmin(st,i);
    	}
    	dfs1(st,0),dfs2(st),dfs3(rt,0),dfs4(rt);
    //	fp(i,1,n)printf("%d %d %d
    ",i,ls[i],rs[i]);
    	return Ot(),0;
    }
    
  • 相关阅读:
    生成微博授权URL及回调地址
    微博三方登录
    celery异步发送短信
    celery配置
    celery原理与组件
    Django----短信验证接口
    Django----图片验证码接口
    编写注册接口
    jwt安装配置
    day19-Exception
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10273322.html
Copyright © 2011-2022 走看看