这是一棵树吗? \operatorname{这是一棵树吗?} 这是一棵树吗?
题目链接: luogu T145300 \operatorname{luogu\ T145300} luogu T145300 / SSL比赛 1516 \operatorname{SSL比赛\ 1516} SSL比赛 1516
题目
DD 和 QQ 在玩游戏, DD 在地上画了一棵树(图论中的树),然后他告诉 QQ 这棵树的度数序列。 QQ 马上说这不是一棵树。 DD 认为自己被 QQ 鄙视了,他们吵了起来。
但 DD 随后发现自己算错了度数序列, QQ 说的是对的。 DD 很奇怪为什么 QQ 反应得这么快。
现在给出一个图的度数序列,你需要做的就是像 QQ 一样:判断这是否可能是一棵树的度数序列。
输入
输入只有一行,首先给出一个整数 N N N ,表示顶点个数,后面跟着 N N N 个整数,表示这个图的度数序列,每个数不超过 100 100 100 。
输出
如果输入可能是一棵树的度数序列,则输出 “Possible” ,否则输出 “Impossible” 。
样例输入1
1 0
样例输出1
Possible
样例输入2
2 1 1
样例输出2
Possible
样例输入3
3 2 2 2
样例输出3
Impossible
样例输入4
3 1 2 1
样例输出4
Possible
数据范围
对于 100 % 100\% 100% 的数据,有 1 ≤ N ≤ 100 1\le N\le 100 1≤N≤100 。
思路
这道题就一道很好做的推论题。
我们可以知道,每个点的度数一定要大于 0 0 0 。
(这个地方我当时没想到还因为可以这样而组成不了树,就只有 80 80 80 了,QAQ)
(不过当 n = 1 n=1 n=1 的时候那个单独的点度数要为 0 0 0 )
接着,可以知道树的边数就是 n − 1 n-1 n−1 ,那我们再判断一下 ( n − 1 ) ∗ 2 (n-1)*2 (n−1)∗2 是否等于度数,就可以判断出来了。
代码
#include<cstdio>
using namespace std;
int n, a[101], sum;
int main() {
scanf("%d", &n);//读入
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);//读入
sum += a[i];//记录总共有多少度数
if (a[i] <= 0) {
//不能有完全独立的单独点(除非点的数量只有一个)
if (n == 1) printf("Possible");//点的数量只有一个
printf("Impossible");
return 0;
}
}
if (sum & 1) {
//度数之和肯定不是单数(显而易见)
printf("Impossible");
return 0;
}
if (sum == (n - 1) * 2) {
//边的数量一定是n-1,就是一半的度数和
printf("Possible");
return 0;
}
else {
printf("Impossible");
return 0;
}
return 0;
}