AtCoder Grand Contest 005 C - Tree Restoring 构造

题意

给出一个序列a[1..n],问能否构造一棵树使得第i个点到最远点的距离恰好为a[i]。
n<=100

分析

有个结论就是任意一个点到树中的最远点必然是直径两个端点中的一个。
那么a中的最大值L必然是树的直径,且最小值不能小于(L+1)/2。
对于其他点x,我们可以在直径上最远点距离为a[x]-1上连一条边到x。
还有画一画不难发现,若L为奇数,则最远点距离为(L+1)/2的点必须恰好有两个。若L为偶数,则最远点距离为L/2的点必须恰好有一个。
然后就没了。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=105;

int n,t[N];

int main()
{
    scanf("%d",&n);int mx=0;
    for (int i=1;i<=n;i++)
    {
        int x;scanf("%d",&x);
        t[x]++;mx=max(mx,x);
    }
    if (!(mx&1)&&t[mx/2]!=1||(mx&1)&&t[(mx+1)/2]>2) {puts("Impossible");return 0;}
    for (int i=(mx+1)/2+1;i<=mx;i++) if (t[i]<2) {puts("Impossible");return 0;}
    for (int i=1;i<(mx+1)/2;i++) if (t[i]) {puts("Impossible");return 0;}
    puts("Possible");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值