P3104 [USACO14MAR]Counting Friends G(图的判定&贪心)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3104 [USACO14MAR]Counting Friends G(图的判定&贪心)相关的知识,希望对你有一定的参考价值。

P3104 [USACO14MAR]Counting Friends G(图的判定&贪心)

枚举错误的数。

因为是无向图,所以度数之和是偶数。

所以 n + 1 n+1 n+1个数的和 s u m sum sum 和 枚举的数的 奇偶性必须相同。

然后就是根据每个点的度数来判定 是否能构成无向图。

采用贪心的思想,每次对度数进行排序。将第一个与后面的每个的点进行抵消。

如果遍历完度数还不能为0说明无解,否则更新再排序继续上过程。

因为减度数之后 可以看出两个有序 的序列,因此采用归并排序,时间复杂度降至 O ( n ) O(n) O(n)

总时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)

参考代码

#include<iostream>
#include<algorithm>
using namespace std;
int main()

	int n, a[502], b[500],c[500],sum=0;
	scanf("%d", &n);
	for (int i = 1; i <= n + 1; i++)
	
		scanf("%d", &a[i]);
		sum += a[i];
	
	int num = 0, res[501];
	for (int i = 1; i <= n + 1; i++)
	
		if (sum % 2 != a[i] % 2)
			continue;
		int index = 0;
		for (int j = 1; j <= n + 1; j++)
			if (j != i)
				b[index++] = a[j];
		sort(b, b + n, [](const int x, const int y) 
			return x > y;
			);
		bool flag = 1;
		for (int j = 1; j <= n; j++)
		
			if (b[0] == 0)
				break;
			int in = 1;
			while (b[0] > 0 && b[in] > 0)
			
				b[0]--;
				b[in++]--;
			
			if (b[0] > 0)
			
				flag = 0;
				break;
			
			int p = 1, q = in, cnt = 0;
			while (p < in && q < n)
				if (b[p] > b[q])
					c[cnt++] = b[p++];
				else
					c[cnt++] = b[q++];
			while (p < in)
				c[cnt++] = b[p++];
			while (q < n)
				c[cnt++] = b[q++];
			for (int k = 0; k < n - 1; k++)
				b[k] = c[k];
			b[n - 1] = 0;
		
		if (flag)
			res[num++] = i;
	
	printf("%d\\n", num);
	for (int i = 0; i < num; i++)
		printf("%d\\n", res[i]);
	return 0;

以上是关于P3104 [USACO14MAR]Counting Friends G(图的判定&贪心)的主要内容,如果未能解决你的问题,请参考以下文章

[USACO14MAR] Counting Friends

P2212 [USACO14MAR]浇地Watering the Fields

洛谷2115 [USACO14MAR]破坏Sabotage

P2115 [USACO14MAR]破坏Sabotage

[USACO14MAR]浇地Watering the Fields

USACO 历年月赛 官方测试数据