Prufer序列
Prufer 序列
作用
将带标号 \(n\) 节点树用 \(n-2\) 个 \([1,n]\) 的整数表示,
即 \(n\) 个点的完全图的生成树和长度为 \(n-2\) 的值域为 \([1,n]\) 的数列构成的双射。
Cayley 定理,\(n\) 个点有标号生成树共 \(n^{n-2}\) 个。Anne's game
算法
树转 Prufer 序列
每次选择一个编号最小的叶节点删除,记录它的父亲。
重复 \(n-2\) 次以后剩下两个节点,算法结束。
堆:\(O(n\log n)\)
指针:\(O(n)\)
指针指向编号最小的叶节点,每次删掉以后,
-
如果产生了新的叶节点,且编号比已经填写完的更小,就直接继续删掉
-
否则++,找到下一个编号最小的叶节点。
Prufer 序列转树
可以得到原树上每个点的度数。
每次选择一个编号最小的度数为1的节点,与当前枚举的Prufer序列的点连接,然后同时减掉两个点的度数,重复 \(n-2\) 次后剩下两个度数为1的点,其中一个是 \(n\) ,连接他们即可。
堆: \(O(n\log n)\)
指针:\(O(n)\)
具体而言,指针指向编号最小的度数为 1 的节点。
每次将它与当前枚举到的 Prufer 序列的点连接之后,
- 如果产生了新的度数为 1 的节点且编号比当前处理“完”的更小,则直接继续将它与下一个 Prufer 序列的点连接,
- 否则++,找到下一个编号最小的度数为 1 的节点。
实现
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mkp make_pair
#define pb push_back
#define PII pair<int, int>
#define PLL pair<ll, ll>
#define ls(x) ((x) << 1)
#define rs(x) ((x) << 1 | 1)
#define fi first
#define se second
const int N = 5e6 + 10;
int n, m, fa[N], p[N], d[N];
void tree_prufer() {
for(int i = 1; i < n; i++)
scanf("%d", &fa[i]), d[fa[i]]++;
for(int i = 1, j = 1; i <= n - 2; i++, j++) {
while(d[j]) j++; p[i] = fa[j];
while(i <= n - 2 && !(--d[p[i]]) && p[i] < j)
p[i + 1] = fa[p[i]], i++;
}
ll ans = 0;
for(int i = 1; i <= n - 2; i++)
ans ^= (1ll * i * p[i]);
printf("%lld\n", ans);
return;
}
void prufer_tree() {
for(int i = 1; i <= n - 2; i++)
scanf("%d", &p[i]), d[p[i]]++;
p[n - 1] = n; d[n]++;
for(int i = 1, j = 1; i < n; i++, j++) {
while(d[j]) j++; fa[j] = p[i];
while(i < n && !(--d[p[i]]) && p[i] < j)
fa[p[i]] = p[i + 1], i++;
}
ll ans = 0;
for(int i = 1; i < n; i++)
ans ^= (1ll * i * fa[i]);
printf("%lld\n", ans);
return;
}
int main(){
scanf("%d%d", &n, &m);
if(m == 1) tree_prufer();
else prufer_tree();
return 0;
}
一些结论:
- 给定所有点度数的有标号无根树个数:\(\frac {(n-2)!} {(d_i-1)!}\)
- \(k\) 个给定的联通块,加 \(k-1\) 条边使得其成为一棵树: \(n^{k-2} \prod {sz_i}\)
证明:
考虑确定度数的,是 \(\sum_{d_i > 0,\sum d_i = 2(k-1)} \frac {(n-2)!} {(d_i-1)!}\prod {sz_i}^{d_i}\),
\(\sum_{d_i-1\ge 0,\sum (d_i-1) = k-2} \frac {(n-2)!} {(d_i-1)!}\prod {sz_i}^{(d_i-1)+1}\),
考虑多元二项式定理 \((\sum_{i=1}^m x_i)^p = \sum_{c_i \ge 0,\sum_{i=1}^m c_i=p} \frac {p!} {\prod (c_i)!}\prod_{i=1}^m {x_i}^{c_i}\)。
所以是 \(n^{k-2} \prod {sz_i}\)
QwQwQ