提供一个 generator / 警示后人
查看原帖
提供一个 generator / 警示后人
354055
Qcfff楼主2024/12/26 10:31

n 是点双数量,v 是值域上限,pq 是点双大小的参数(源汇点间的链数上限和链长上限,开到 575\sim7 就够用)。生成点数不固定,因此不能生成大数据,可能爆范围。

#include<bits/stdc++.h>
#define int long long
using namespace std;
mt19937 gen(chrono::steady_clock().now().time_since_epoch().count());
int rnd(int l,int r){
	return gen()%(r-l+1)+l;
}
const int N=5e5+10;
int cnt;
int fa[N],st[N],id[N];
vector<pair<int,int>> e,now;
signed main(){
	int n=3,p=5,q=7;
	int cnt=n;
	for(int x=2;x<=n;x++){
		fa[x]=rnd(1,x-1);
		int num=rnd(1,p);
		bool one=false;
		now.clear();
		int top=2;
		st[1]=fa[x],st[2]=x;
		for(int i=1;i<=num;i++){
			int len=rnd(1+one,(num==1?1:q));
			one|=(len==1);
			int lst=1;
			for(int j=1;j<len;j++){
				st[++top]=++cnt;
				now.push_back(make_pair(lst,top));
				lst=top;
			}
			now.push_back(make_pair(lst,2));
		}
		shuffle(st+1,st+1+top,gen);
		for(auto it:now){
			e.push_back(make_pair(st[it.first],st[it.second]));
		}
	}
	int q=10,v=10;
	for(int i=1;i<=cnt;i++){
		id[i]=i;
	}
	shuffle(id+1,id+1+cnt,gen);
	cout<<cnt<<" "<<e.size()<<" "<<q<<"\n";
	for(auto it:e){
		if(rnd(0,1)){
			swap(it.first,it.second);
		}
		cout<<id[it.first]<<" "<<id[it.second]<<" "<<rnd(1,v)<<"\n";
	}
	while(q--){
		cout<<rnd(1,cnt)<<" "<<rnd(1,cnt)<<"\n";
	}
	return 0;
}

一些可能写挂的地方:

  • 点双两点有属于源汇点的分类讨论

  • 点双的源点汇点判成同一个点

  • 忘记取模

  • LCA 儿子处两点是否是同一个点双的特判

  • 两点是祖先关系的情况

2024/12/26 10:31
加载中...