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(图的判定&贪心)的主要内容,如果未能解决你的问题,请参考以下文章
P2212 [USACO14MAR]浇地Watering the Fields