UOJ 460

求一个$n$个点的完全图最多能有几个边不重复的生成树,并输出方案。

$$3\le n \le 2000$$

由于完全图边数为$\frac{n(n-1)}{2}$,而一棵生成树的边数为$n-1$,所以上界是$\lfloor \frac{n}{2} \rfloor$,下面给出一个构造方案来证明这个上界是紧的。

用增量法,设当前有$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", 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 }

 

posted @ 2019-02-09 18:04  sjkmost  阅读(201)  评论(0编辑  收藏  举报