[CF1041E]Tree Reconstruction
Posted memory-of-winter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF1041E]Tree Reconstruction相关的知识,希望对你有一定的参考价值。
题目大意:有一棵树,现在给你每条树边被去掉时,形成的两个联通块中点的最大的编号分别是多少,问满足条件的树存不存在,存在输出方案
题解:一条边的两个编号中较大的一个一定是$n$,否则无解。
开始构造这棵树,发现一定可以是一条链,可以钦定$n$在链的一端,把较小值(即前缀$max$)排序,每次变化是就把该位赋成变化值,否则就从前面随便取一个没用过的出来(若没有则无法构造)。
为什么一定可以是链呢?发现无法构造的条件是排序后$i>max_i$,而此时也构造不出树(显然)。
卡点:无
C++ Code:
#include <cstdio> #include <algorithm> #define maxn 1010 int n; int s[maxn], p[maxn]; bool used[maxn]; int main() { scanf("%d", &n); for (int i = 1, a, b; i < n; i++) { scanf("%d%d", &a, &b); if (a > b) std::swap(a, b); if (b != n) { puts("NO"); return 0; } s[i] = a; } std::sort(s + 1, s + n); for (int i = 1; i < n; i++) { if (s[i] != s[i - 1]) used[p[i] = s[i]] = true; else { bool found = false; for (int j = 1; j < s[i]; j++) if (!used[j]) { used[p[i] = j] = found = true; break; } if (!found) { puts("NO"); return 0; } } } p[n] = n; puts("YES"); for (int i = 1; i < n; i++) { printf("%d %d ", p[i], p[i + 1]); } return 0; }
以上是关于[CF1041E]Tree Reconstruction的主要内容,如果未能解决你的问题,请参考以下文章
codeforces 1041 E. Tree Reconstruction 和度数有关的构造树
CF 1039D You Are Given a Tree && CF1059E Split the Tree 的贪心解法