题意:给一个N个点的完全图,让你输出k个边不重复的生成树。
分析:如果k > n/2直接无解,否则我们用类似数学归纳法的方法构造;可以发现从2开始才有解,而且n每增加2其构造方案数才能+1,当n为奇数时,我们可以让第n个点直接向前边的点连边来继承n-1的所有方案;当n为偶数时,我们可以直接继承n-2的所有方案,并且让[1,(n-2)/2]的边连向n-1,[(n-2)/2+1,n-2]连向n,再增加一条n到n-1的边,这样方案数就又能增加一种。
#include <cstdio>
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
int n,k;
vector<pii> edg[205];
int main()
{
scanf("%d%d",&n,&k);
if(k > n/2)
{
cout<<"-1"<<endl;
return 0;
}
for(int i = 2;i <= min(n,2*k);i++)
{
if(i & 1)
for(int j = i/2+1;j < i;j++) edg[j-i/2].push_back(make_pair(j,i));
else
{
for(int j = 1;j < i/2;j++) edg[j].push_back(make_pair(j,i));
edg[i/2].push_back(make_pair(i-1,i));
for(int j = 1;j <= i-2;j++) edg[i/2].push_back(make_pair((j <= (i-2)/2 ? i-1 : i),j));
}
}
for(int i = 2*k+1;i <= n;i++)
for(int j = 1;j <= k;j++) edg[j].push_back(make_pair(j,i));
for(int i = 1;i <= k;i++)
{
for(auto j : edg[i]) cout<<j.first<<" "<<j.second<<endl;
cout<<endl;
}
}