UOJ 460
Posted sjkmost
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UOJ 460相关的知识,希望对你有一定的参考价值。
求一个$n$个点的完全图最多能有几个边不重复的生成树,并输出方案。
$$3le n le 2000$$
由于完全图边数为$frac{n(n-1)}{2}$,而一棵生成树的边数为$n-1$,所以上界是$lfloor frac{n}{2} floor$,下面给出一个构造方案来证明这个上界是紧的。
用增量法,设当前有$k$个点($k$为偶数),我们再加入$2$个点,设为第$k+1,k+2$个。
对于原有的$frac{k}{2}$棵树,在第$i$棵树上加入边$(i,k+1),(i+frac{k}{2},k+2)$。而对于新的树$T_{frac{k}{2}+1}$,$forall i in [1,frac{k}{2}],(i,k+2),(i+frac{k}{2},k+1) in E_{T_{frac{k}{2}+1}}$,最后在新树上加入边$(k+1,k+2)$即可。
如果$n$是奇数,最后所有树再向$n$连一条边即可。
1 const int MAXN = 2000 + 5; 2 3 std::vector<std::pair<int, int>> G[MAXN]; 4 5 int main() { 6 int n; 7 scanf("%d", &n); 8 printf("%d ", n >> 1); 9 for (int i = 2; i <= n; i += 2) { 10 For(j, 1, (i - 2) >> 1) { 11 G[j].push_back(std::make_pair(j, i - 1)); 12 G[j].push_back(std::make_pair(j + ((i - 2) >> 1), i)); 13 } 14 G[i >> 1].push_back(std::make_pair(i - 1, i)); 15 For(j, 1, (i - 2) >> 1) { 16 G[i >> 1].push_back(std::make_pair(j, i)); 17 G[i >> 1].push_back(std::make_pair(j + ((i - 2) >> 1), i - 1)); 18 } 19 } 20 if (n & 1) { 21 For(i, 1, n >> 1) { 22 G[i].push_back(std::make_pair(i, n)); 23 } 24 } 25 For(i, 1, n >> 1) { 26 for (auto &x: G[i]) { 27 printf("%d %d ", x.first, x.second); 28 } 29 puts(""); 30 } 31 return 0; 32 }
以上是关于UOJ 460的主要内容,如果未能解决你的问题,请参考以下文章