题意
给出一个序列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;
}