对拍-随机树生成O(n)
对拍用的,思路很简单。
用并查集维护这棵树。
考虑以1为根节点,那么我们只要对于n到2的每一个节点i,让random(1,i-1)为它的根,可以保证这样不会成环且连通。
如果不要求一定以1为根节点
- 一种方法是,我们可以认为构造的这棵树为无根树,然后换根输出就好。
- 另一种方法就是下面写的用random_shuffle函数获得一个随机的1~n的排列,然后对应着输出就好。
都是O(n)
//随机树生成O(n)
#include<bits/stdc++.h>
using namespace std;
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef long long ll;
typedef unsigned long long ull;
stringstream ss;
int dsu[1000005];//1e6
int mapp[10000005];
void create(){
int n=random(1,10);
for(int i=n;i>=2;--i){
dsu[i]=random(1,i-1);//生成一颗以1为根节点的树
}
//以上为以1为根,随机还要重新编号对应一下,可以借助随机乱序函数
for(int i=1;i<=n;++i) mapp[i]=i;
random_shuffle(mapp+1,mapp+n+1);//随机排列
//打印树,必要可以随机边权
printf("%d\n",n);
for(int i=2;i<=n;++i){
printf("%d %d\n",mapp[i],mapp[ dsu[i] ]);
}
return;
}
int main()
{
//IOS;
srand(time(NULL));
int t=1;
while(t--) create();
return 0;
}