• #树,搜索#NOIP2020.9.26模拟tom


    题目


    分析

    考虑最极端的情况也就是TOM天天吃早餐肠或者晚餐肠,
    那么早餐肠和晚餐肠应分别构成一个互不相交连通块,
    所以题目转换成是否有一个点的子树大小为(a)(b)
    将这个点与它父亲的边断开就可以分别编号了


    代码

    #include <cstdio>
    #include <cctype>
    #include <queue>
    #define rr register
    using namespace std;
    const int N=100011;
    struct node{int y,next;}e[N<<1];
    int a[N],n,k=1,son[N],rt1,rt2,now,as[N],A,B;
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline void print(int ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    inline void dfs1(int x,int fa){
    	son[x]=1;
    	for (rr int i=as[x];i;i=e[i].next)
    	    if (e[i].y!=fa) dfs1(e[i].y,x),son[x]+=son[e[i].y];
        if (son[x]==A) rt1=x,rt2=fa;
            else if (son[x]==B) rt1=fa,rt2=x;
    }
    inline void dfs2(int x,int opt,int fa){
    	a[x]=opt*(now--);
    	for (rr int i=as[x];i;i=e[i].next)
    	    if (!a[e[i].y]&&e[i].y!=fa)
    		    dfs2(e[i].y,opt,fa);
    }
    signed main(){
    	freopen("tom.in","r",stdin);
    	freopen("tom.out","w",stdout);
    	n=iut(); A=iut(); B=iut();
    	for (rr int i=1;i<n;++i){
    		rr int x=iut(),y=iut();
    		e[++k]=(node){y,as[x]},as[x]=k;
    		e[++k]=(node){x,as[y]},as[y]=k;
    	}
    	dfs1(1,0);
    	if (!rt1&&!rt2) return !printf("-1");
    	now=A,dfs2(rt1,1,rt2),now=B,dfs2(rt2,-1,rt1);
    	for (rr int i=1;i<=n;++i){
    		if (a[i]<0) putchar('-'),print(-a[i]);
    		    else print(a[i]);
    		putchar(10);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Codeforces 512D
    Codeforces Gym 101480C
    Codeforces 575A
    Codeforces Round #691 (Div. 2) 题解
    .net Core 中文等非英文文字html输出编码输出问题
    .net5 grpc服务在windows上的架设方法
    北大集训 2020 游记
    北大集训2020游记
    Tricks -「网络流」经典模型汇总
    Solution -「BJWC 2018」「洛谷 P4486」Kakuro
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13817014.html
Copyright © 2020-2023  润新知