Generator for Cactus

首先生成一棵树,然后对这棵树进行随机链剖分,处理出每个点对应的链顶。最后随机添加的非树边条数,随机一个点,若对应链顶没有被 作为链顶 被非树边连接过,则可以接受这一条非树边。

注意,这个版本是存在重边的,如果想去掉重边,再加个 \(\rm dep\) 数组判断即可。

# include <bits/stdc++.h>
using namespace std;

# define rg register

const int maxn=2e5+5;

bool vis[maxn];
int h[maxn],tot=1,x[maxn],y[maxn],tp[maxn];
struct edge { int to,nxt; } b[maxn<<1];

inline void add(rg int aa,rg int bb) {
	b[tot].to=bb, b[tot].nxt=h[aa], h[aa]=tot++;
}

void dfs(rg int now,rg int lat) {
	rg int jud=false;
	for(rg int i=h[now]; ~i; i=b[i].nxt) {
		rg int u=b[i].to; if(u==lat) continue;
		if(!jud) tp[u]=tp[now], jud=true;
		else tp[u]=u;
		dfs(u,now);
	}
}

int main() {
	freopen("data.in","w",stdout);
	memset(h,-1,sizeof(h));
	mt19937 SEED(time(0));
	uniform_int_distribution <int> makeNM(1,10);
	int n=makeNM(SEED)+2, m=n-1;
	rg int aa,bb; tp[1]=1;
	for(rg int i=2;i<=n;++i) {
		aa=rand()%(i-1)+1, bb=i;
		x[i-1]=aa, y[i-1]=bb;
		add(aa,bb), add(bb,aa);
	}
	dfs(1,0);
	rg int cnt=makeNM(SEED)+1;
	for(rg int i=1;i<=cnt;i++) {
		aa=rand()%n+1; bb=tp[aa];
		if(aa!=bb && !vis[bb]) {
			x[++m]=aa, y[m]=bb;
			vis[bb]=1;
		}
	}
	printf("%d %d\n",n,m);
	for(rg int i=1;i<=m;i++) 
		printf("%d %d\n",x[i],y[i]);
	return 0;
}
posted on 2022-05-18 22:44  Oxide  阅读(33)  评论(0编辑  收藏  举报