题解:P1701 [USACO19OPEN] Cow Evolution B
P1701 [USACO19OPEN] Cow Evolution B 题解
思路分析
先换个角度看问题,对于每一种特性,记录哪些子种群拥有它。例如,特性 flying 出现在第
一种特性只出现一次,所以拥有这种特性的奶牛一定集中在进化树的某一根树枝下面,不可能东一块、西一块。
那么拿出任意两种特性来比较,它们只能有下面三种关系:
- 没有子种群同时拥有这两种特性;
- 拥有第一种特性的子种群,全都拥有第二种特性;
- 拥有第二种特性的子种群,全都拥有第一种特性。
用集合表示,就是两个集合要么完全分开,要么一个被另一个包含。
所以做法很简单:枚举任意两种特性,只要发现它们有一部分重合,但谁也不完全包含谁,就输出 no。如果所有特性都没有这种冲突,就输出 yes。
参考代码
#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
const int N = 35, M = 635;
int n, cnt, a[M];
string s;
map<string, int> m;
int main() {
scanf("%d", &n);
for (int i = 0, x; i < n; ++i) {
scanf("%d", &x);
for (int j = 0; j < x; ++j) {
cin >> s;
if (!m.count(s)) m[s] = ++cnt;
a[m[s]] |= 1 << i;
}
}
for (int i = 1; i <= cnt; ++i) {
for (int j = i + 1; j <= cnt; ++j) {
int t = a[i] & a[j];
if (t && t != a[i] && t != a[j]) {
puts("no");
return 0;
}
}
}
puts("yes");
return 0;
}