tom

题目描述

众所周知,Tom 猫对香肠非常感兴趣。有一天,Tom 家里的女主人赏给了Tom 一大堆香肠。这些香肠太多了,以至于Tom 一顿吃不完,于是它把这些香肠串成了一棵树,树的每个节点上都有一个香肠。

Tom 需要给这些香肠进行编号,其中有 aa 个香肠需要编号为 1,2,\cdots,a1,2,,a 中的不重复的编号,作为早餐肠,剩下的 bb 个香肠需要编号为-1,-2,\cdots,-b1,2,,b中的不重复的编号,作为晚餐肠。

Tom 每天会随机吃一顿饭,可能是早饭,也可能是晚饭。如果是吃早饭,Tom 会吃掉编号绝对值最小的早餐肠,反之吃掉编号绝对值最小的晚餐肠。

如果一根香肠被吃掉了,那么与它相连的树上的边都会断掉,因此剩下的香肠可能会因此变成若干棵树,即变得不再连通。这是Tom 不希望发生的事。

请给这些香肠编号,使得无论Tom 如何安排早饭和晚饭,整棵树一直都是连通的。

输入格式

第一行三个正整数 n,a,bn,a,b,代表节点的数目,早餐肠的数目,晚餐肠的数目。保证 a + b = na+b=n

第二行开始,共 n-1n1 行,每行两个正整数 u,vu,v,代表树上一条边。

输出格式

共 nn 行,第 ii 行输出第 ii 个节点的编号。

如果存在多种编号方式,请随意输出一种。如果不存在这样的编号方式,请输出 -11。

样例

样例输入1

6 3 3
1 2
2 3
2 4
4 5
4 6

样例输出1

1
3
2
-3
-2
-1

样例1 说明

编号后,无论如何安排早晚餐,香肠组成的树都是一直联通的。

另外,其它的编号方式也是可行的,比如2,3,1,-3,-1,-2 等。

样例2

下发了额外的一个大型样例文件。

数据范围与提示

测试点编号 n的范围 特殊性质
1-3 n \le 10n10
4 n \le 2000n2000
5,6,7 n \le 10^5n105 树是一条以1, n 为端点的链
8 n \le 10^5n105 a=1a=1
9,10 n \le 10^5n105

对于全部的数据,n \le 10^5, a + b = n,1 \le a, bn105,a+b=n,1a,b

来源

CSP-S 2019模拟 长沙一中2


Solution
因为某些sb错误爆零了
一个合法的方案一定是一棵大小为a或b的子树一种颜色,其他的另一种颜色。
于是dfs找子树再拓扑两次就好了。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define maxn 100005
using namespace std;
int n,a,b,head[maxn],tot,sz[maxn];
int F,pl,f[maxn],in[maxn],dfn[maxn],ed[maxn],dy[maxn],sc;
int col[maxn],flag[maxn];
queue<int>q;
struct node{
    int v,nex;
}e[maxn*2];
void add(int t1,int t2){
    e[++tot].v=t2;e[tot].nex=head[t1];head[t1]=tot;
}
void dfs(int k,int fa){
    sz[k]=1;f[k]=fa;dfn[k]=++sc;dy[sc]=k;
    for(int i=head[k];i;i=e[i].nex){
        if(e[i].v==fa)continue;
        dfs(e[i].v,k);
        sz[k]+=sz[e[i].v];
    }
    ed[k]=sc;
    if(sz[k]==a)F=1,pl=k;
    if(sz[k]==b)F=-1,pl=k;
}
int main(){
    cin>>n>>a>>b;
    for(int i=1,t1,t2;i<n;i++){
        scanf("%d%d",&t1,&t2);
        add(t1,t2);add(t2,t1);
        in[t1]++;in[t2]++;
    }
    dfs(1,0);
    if(!F){puts("-1");return 0;}
    for(int i=1;i<=n;i++){
        if(dfn[i]>=dfn[pl]&&dfn[i]<=ed[pl]){
            flag[i]=1;
            if(in[i]==1)q.push(i);
        }
    }
    int now=0;
    while(!q.empty()){
        int k=q.front();q.pop();col[k]=F*(++now);
        for(int i=head[k];i;i=e[i].nex){
            in[e[i].v]--;
            if(in[e[i].v]==1&&flag[e[i].v])q.push(e[i].v);
        }
    }
    for(int i=1;i<=n;i++)if(!flag[i]&&i!=f[pl]&&in[i]==1)q.push(i);
    in[f[pl]]=n;
    now=0;
    while(!q.empty()){
        int k=q.front();q.pop();col[k]=(-F)*(++now);
        for(int i=head[k];i;i=e[i].nex){
            in[e[i].v]--;
            if(in[e[i].v]==1&&!flag[e[i].v])q.push(e[i].v);
        }
    }
    col[f[pl]]=(-F)*(++now);
    for(int i=1;i<=n;i++)printf("%d\n",col[i]);puts("");
    return 0;
}
View Code
 

猜你喜欢

转载自www.cnblogs.com/liankewei/p/11849884.html
tom