这是一棵树吗?

这是一棵树吗? ⁡ \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 1N100

思路

这道题就一道很好做的推论题。

我们可以知道,每个点的度数一定要大于 0 0 0
(这个地方我当时没想到还因为可以这样而组成不了树,就只有 80 80 80 了,QAQ)
(不过当 n = 1 n=1 n=1 的时候那个单独的点度数要为 0 0 0

接着,可以知道树的边数就是 n − 1 n-1 n1 ,那我们再判断一下 ( n − 1 ) ∗ 2 (n-1)*2 (n1)2 是否等于度数,就可以判断出来了。

代码

#include

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;
}

你可能感兴趣的:(#,推论,#,树,树,推论)