namespace util { mt19937 rd(0); int randint(int x) { assert(x > 0); return uniform_int_distribution(0, x-1)(rd); } void shuffle_adj_lists(vector> &adj) { for (auto &a: adj) ranges::shuffle(a, rd); } vector> random_tree(int n) { vector> adj(n); vector> components(n); for (int i = 0; i < n; i++) components[i].push_back(i); while (components.size() > 1) { int c1 = randint(components.size()); int c2 = randint(components.size()-1); c2 += (c2 >= c1); int v1 = components[c1][randint(components[c1].size())]; int v2 = components[c2][randint(components[c2].size())]; adj[v1].push_back(v2); adj[v2].push_back(v1); if (components[c1].size() < components[c2].size()) swap(c1, c2); for (int v: components[c2]) components[c1].push_back(v); swap(components[c2], components.back()); components.pop_back(); } shuffle_adj_lists(adj); return adj; } vector> path(int n) { vector> adj(n); for (int i = 1; i < n; i++) { adj[i-1].push_back(i); adj[i].push_back(i-1); } return adj; } template void shuffle_graph(vector> &adj, Ts &...vertex) { int n = adj.size(); vector perm(n); iota(perm.begin(), perm.end(), 0); ranges::shuffle(perm, rd); vector> new_adj(n); for (int i = 0; i < n; i++) { auto &a = new_adj[perm[i]] = move(adj[i]); for (int &v: a) v = perm[v]; } adj = move(new_adj); shuffle_adj_lists(adj); ((vertex = perm[vertex]), ...); } }