n 是点双数量,v 是值域上限,p 和 q 是点双大小的参数(源汇点间的链数上限和链长上限,开到 5∼7 就够用)。生成点数不固定,因此不能生成大数据,可能爆范围。
#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 儿子处两点是否是同一个点双的特判
两点是祖先关系的情况