Guest User

Untitled

a guest
Aug 9th, 2021
441
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.99 KB | None | 0 0
  1. #include <cassert>
  2. #include <ctime>
  3. #include <iostream>
  4. #include <numeric>
  5. #include <random>
  6. #include <set>
  7. #include <vector>
  8.  
  9. using namespace std;
  10.  
  11. #define ALL(c) c.begin(), c.end()
  12. #define SZ(c) (int)c.size()
  13.  
  14. mt19937 rnd;
  15. void gen();
  16.  
  17. int main() {
  18.   assert(freopen("test.in", "r", stdin));
  19.   assert(freopen("test.out", "w", stdout));
  20.   ios_base::sync_with_stdio(false);
  21.   cin.tie(NULL);
  22.   cout.tie(NULL);
  23.   cerr.precision(3);
  24.   cerr << fixed;
  25.   int start = (int)clock();
  26.   rnd = mt19937(time(NULL));
  27.   gen();
  28.   double run_time = (double)(clock() - start) / CLOCKS_PER_SEC;
  29.   cerr << "TIME: " << run_time << '\n';
  30.   return 0;
  31. }
  32.  
  33. const int N = 1e5 + 7;
  34.  
  35. int n, m;
  36. vector<pair<int, int>> edges;
  37. vector<int> g[N];
  38.  
  39. int par[N], sz[N];
  40.  
  41. void build(int n) {
  42.   iota(par, par + n, 0);
  43.   fill(sz, sz + n, 1);
  44. }
  45.  
  46. int find(int x) { return x == par[x] ? x : par[x] = find(par[x]); }
  47.  
  48. bool join(int x, int y) {
  49.   x = find(x);
  50.   y = find(y);
  51.   if (x != y) {
  52.     if (sz[x] > sz[y]) {
  53.       swap(x, y);
  54.     }
  55.     par[x] = y;
  56.     sz[y] += sz[x];
  57.   }
  58.   return x != y;
  59. }
  60.  
  61. bool check() {
  62.   build(n);
  63.   int cnt = 0;
  64.   for (auto a : edges) {
  65.     cnt += join(a.first, a.second);
  66.   }
  67.   return cnt == n - 1;
  68. }
  69.  
  70. void build_complete_graph() {
  71.   for (int v = 0; v < n; ++v) {
  72.     for (int u = 0; u < v; ++u) {
  73.       edges.push_back({v, u});
  74.     }
  75.   }
  76. }
  77.  
  78. void build_big_graph() {
  79.   const int C = 8;
  80.   set<pair<int, int>> e;
  81.   int attempt = 1;
  82.   do {
  83.     cerr << "ATTEMPT #" << attempt++ << '\n';
  84.     while (SZ(e) != max(m, C * n)) {
  85.       int v = rnd() % (n - 1) + 1;
  86.       int u = rnd() % v;
  87.       if (!e.count({v, u}) && !e.count({u, v})) {
  88.         e.insert({v, u});
  89.       }
  90.     }
  91.     edges.clear();
  92.     for (auto a : e) {
  93.       edges.push_back(a);
  94.     }
  95.   } while (!check());
  96. }
  97.  
  98. int tin[N], ct = 1;
  99. int up[N];
  100. vector<int> biconnected_edges;
  101.  
  102. void dfs(int v, int last, int id) {
  103.   up[v] = tin[v] = ct++;
  104.   for (int i : g[v]) {
  105.     int u = (edges[i].first ^ edges[i].second ^ v);
  106.     if (!tin[u]) {
  107.       dfs(u, v, i);
  108.       up[v] = min(up[v], up[u]);
  109.     } else if (u != last) {
  110.       up[v] = min(up[v], tin[u]);
  111.     }
  112.   }
  113.   if (up[v] != tin[v] && last != v) {
  114.     biconnected_edges.push_back(id);
  115.   }
  116. }
  117.  
  118. void build_biconnected_edges() {
  119.   biconnected_edges.clear();
  120.   for (int v = 0; v < n; ++v) {
  121.     g[v].clear();
  122.   }
  123.   for (int i = 0; i < SZ(edges); ++i) {
  124.     auto [v, u] = edges[i];
  125.     g[v].push_back(i);
  126.     g[u].push_back(i);
  127.   }
  128.   ct = 1;
  129.   fill(tin, tin + n, 0);
  130.   dfs(0, 0, -1);
  131. }
  132.  
  133. void gen() {
  134.   cin >> n >> m;
  135.   assert(m >= n - 1 && m <= n * 1LL * (n - 1) / 2);
  136.   // build_complete_graph();
  137.   build_big_graph();
  138.   while (SZ(edges) > m) {
  139.     build_biconnected_edges();
  140.     int i = biconnected_edges[rnd() % SZ(biconnected_edges)];
  141.     swap(edges[i], edges.back());
  142.     edges.pop_back();
  143.   }
  144.   assert(check());
  145.   cout << n << ' ' << m << '\n';
  146.   for (auto e : edges) {
  147.     cout << e.first + 1 << ' ' << e.second + 1 << '\n';
  148.   }
  149. }
Advertisement
Add Comment
Please, Sign In to add comment