Advertisement
Guest User

Untitled

a guest
Mar 22nd, 2019
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.64 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int N = 6e5 + 5;
  6.  
  7. struct edge {
  8.     int num, to;
  9.     edge(int num, int to) : num(num), to(to) { }
  10. };
  11.  
  12. int n, m, p, T, C, timer, id_color = 1, link[N], tin[N], fup[N], color[N], cnt[N];
  13. bool block[N];
  14. vector<pair<int, int> > E;
  15.  
  16. vector<int> t[N];
  17. vector<edge> g[N];
  18.  
  19. void read() {
  20.     scanf("%d%d", &n, &m);
  21.     for (int i = 0; i < m; ++i) {
  22.         int a, b;
  23.         scanf("%d%d", &a, &b);
  24.         if (a > b) swap(a, b);
  25.         E.push_back({a, b});
  26.     }
  27.     scanf("%d", &T);
  28. }
  29.  
  30. bool fn(int n) {
  31.     if (n > 2) return false;
  32.     if (n == 1)
  33.         printf("0");
  34.     else {
  35.         if (m >= 2)
  36.             printf("0");
  37.         else {
  38.             printf("1\n");
  39.             if (T == 1)
  40.                 printf("1 2");
  41.         }
  42.     }
  43.     return true;
  44. }
  45.  
  46. void dfs_bridge(int v, int last_num = -1) {
  47.     fup[v] = tin[v] = ++timer;
  48.     for (auto& edge: g[v]) {
  49.         int to = edge.to, num = edge.num;
  50.         if (num == last_num) continue;
  51.         if (tin[to])
  52.             fup[v] = min(fup[v], tin[to]);
  53.         else {
  54.             dfs_bridge(to, num);
  55.             fup[v] = min(fup[v], fup[to]);
  56.             if (tin[v] < fup[to])
  57.                 block[num] = true;
  58.         }
  59.     }
  60. }
  61.  
  62. void dfs_tree(int v, int cur_color = 1) {
  63.     color[v] = cur_color;
  64.     link[color[v]] = v;
  65.     for (auto& edge: g[v]) {
  66.         int to = edge.to, num = edge.num;
  67.         if (color[to]) continue;
  68.         if (!block[num])
  69.             dfs_tree(to, cur_color);
  70.         else {
  71.             int cur_color = ++id_color;
  72.             int a = color[v], b = cur_color;
  73.             t[a].push_back(b);
  74.             t[b].push_back(a);
  75.             dfs_tree(to, cur_color);
  76.         }
  77.     }
  78. }
  79.  
  80. int find_cnt(int v, int last = -1) {
  81.     bool leaf = true;
  82.     for (auto to: t[v])
  83.         if (to != last) {
  84.             cnt[v] += find_cnt(to, v);
  85.             leaf = false;
  86.         }
  87.     if (leaf) cnt[v] = 1;
  88.     return cnt[v];
  89. }
  90.  
  91. void find_centroid(int v, int last = -1) {
  92.     pair<int, int> Max = {0, 0};
  93.     for (auto to: t[v])
  94.         if (to != last)
  95.             Max = max(Max, make_pair(cnt[to], to));
  96.     if (Max.first > (p + 1) / 2)
  97.         find_centroid(Max.second, v);
  98.     else
  99.         C = v;
  100. }
  101.  
  102. void find_leaves(auto& q, int v, int last) {
  103.     bool leaf = true;
  104.     for (auto to: t[v])
  105.         if (to != last) {
  106.             leaf = false;
  107.             find_leaves(q, to, v);
  108.         }
  109.     if (leaf) q.push_back(v);
  110. }
  111.  
  112. auto find_res(int v) {
  113.     vector<vector<int> > q;
  114.     int k = 0;
  115.     for (auto to: t[v]){
  116.         vector<int> tmp;
  117.         find_leaves(tmp, to, v);
  118.         q.push_back(tmp);
  119.         k += 1;
  120.     }
  121.     vector<pair<int, int> > res;
  122.     set<pair<int, int> > st;
  123.     for (int i = 0; i < k; ++i)
  124.         st.insert({(int)q[i].size(), i});
  125.     int last = 0;
  126.     while (st.size() > 1) {
  127.         int a = st.begin() -> second;
  128.         int b = st.rbegin() -> second;
  129.         st.erase(st.begin());
  130.         st.erase(*st.rbegin());
  131.         int v = link[q[a].back()];
  132.         int u = link[q[b].back()];
  133.         res.push_back({v, u});
  134.         q[a].pop_back();
  135.         q[b].pop_back();
  136.         if (!q[a].empty())
  137.             st.insert({(int)q[a].size(), a});
  138.         else
  139.             last = v;
  140.         if (!q[b].empty())
  141.             st.insert({(int)q[b].size(), b});
  142.         else
  143.             last = u;
  144.     }
  145.     if (!st.empty()) {
  146.         auto& tmp = q[st.begin() -> second];
  147.         while (!tmp.empty()) {
  148.             int v = tmp.back();
  149.             res.push_back({link[v], last});
  150.             tmp.pop_back();
  151.         }
  152.     }
  153.     return res;
  154. }
  155.  
  156. void solve() {
  157.     read();
  158.     if (fn(n)) return;
  159.     for (int i = 0; i < m; ++i) {
  160.         int a = E[i].first, b = E[i].second;
  161.         g[a].push_back(edge(i, b));
  162.         g[b].push_back(edge(i, a));
  163.     }
  164.  
  165.     srand(time(nullptr));
  166.  
  167.     dfs_bridge(1);
  168.     dfs_tree(1);
  169.  
  170.     n = id_color;
  171.     int k = 0;
  172.     for (int i = 1; i <= n; ++i)
  173.         k += t[i].size() == 1;
  174.  
  175.     printf("%d\n", (k + 1) / 2);
  176.     if (T == 1) {
  177.         if (n == 2) {
  178.             int a = 1, b = t[1].front();
  179.             printf("%d %d", link[a], link[b]);
  180.             return;
  181.         }
  182.         int v = 0;
  183.         for (int i = 1; i <= n; ++i)
  184.             if (t[i].size() != 1)
  185.                 v = i;
  186.         find_cnt(v);
  187.         p = cnt[v];
  188.         find_centroid(v);
  189.         auto res = find_res(C);
  190.         assert(res.size() == (k + 1) / 2);
  191.         for (auto it: res)
  192.             printf("%d %d\n", it.first, it.second);
  193.     }
  194. }
  195.  
  196. int main() {
  197.     //freopen("input.txt", "r", stdin);
  198.     solve();
  199.     return 0;
  200. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement