题解 P6147 【[USACO20FEB]Delegation G】
StudyingFather · · 题解
原图是一棵无根树,为了方便起见,我们指定
接下来我们从
画个图后会发现,一条经过点
显然,对于某个点
于是我们可以对每个点
最后如果存在一个
这个做法的效率如何呢?对于一个
数据范围内最坏情况下,-O2 优化选项),在 luogu 上提交时 开启 -O2 选项测试点
这种情况下可以考虑对星形图特判处理。
下面是作者在比赛时提交的代码:
(UPD 2021/08/10:感谢 @zhaohaikun 指出了我题解中的一处 实现细节问题,代码已经修正)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
vector<int> e[100005];
int siz[100005], n;
bool dfs(int u, int fa, int k) {
map<int, int> m;
for (auto v : e[u])
if (v != fa) {
if (!dfs(v, u, k)) return false;
int tmp = k - siz[v];
if (m.count(tmp) && m[tmp]) {
m[tmp]--;
if (m[tmp] == 0) m.erase(tmp);
siz[u] -= tmp;
} else if (k != siz[v])
siz[u] += siz[v], m[siz[v]]++;
}
siz[u]++;
int rem = 0;
for (auto p : m) rem += p.second;
return rem <= 1;
}
int main() {
freopen("deleg.in", "r", stdin);
freopen("deleg.out", "w", stdout);
ios::sync_with_stdio(false);
cin >> n;
n--;
for (int i = 1; i <= n; i++) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
for (int i = 1; i <= n; i++) {
if (n % i)
cout << 0;
else {
memset(siz, 0, sizeof(siz));
if (dfs(1, 0, i))
cout << 1;
else
cout << 0;
}
}
cout << endl;
return 0;
}