Advertisement
vlatkovski

POI23 Niebanalne podróże (nie)

Aug 13th, 2019
341
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.40 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6.  
  7. void __print(int x) {cerr << x;}
  8. void __print(long x) {cerr << x;}
  9. void __print(long long x) {cerr << x;}
  10. void __print(unsigned x) {cerr << x;}
  11. void __print(unsigned long x) {cerr << x;}
  12. void __print(unsigned long long x) {cerr << x;}
  13. void __print(float x) {cerr << x;}
  14. void __print(double x) {cerr << x;}
  15. void __print(long double x) {cerr << x;}
  16. void __print(char x) {cerr << '\'' << x << '\'';}
  17. void __print(const char *x) {cerr << '\"' << x << '\"';}
  18. void __print(const string &x) {cerr << '\"' << x << '\"';}
  19. void __print(bool x) {cerr << (x ? "true" : "false");}
  20.  
  21. template<typename T, typename V>
  22. void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
  23. template<typename T>
  24. void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
  25. void _print() {cerr << "]\n";}
  26. template <typename T, typename... V>
  27. void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
  28. #ifndef ONLINE_JUDGE
  29. #define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
  30. #else
  31. #define debug(x...)
  32. #endif
  33.  
  34. const int mod = 1e9 + 7;
  35. const int maxn = 500010;
  36. const int maxm = 1000010;
  37.  
  38. int n, m;
  39. vector<int> adj[maxn];
  40.  
  41. const int NOT_FOUND = -1, STOPSTOPSTOP = -2;
  42. int bcc_size;
  43. int bcc_sum;
  44. int last[maxn];
  45. int degree[maxn];
  46.  
  47. int timer;
  48. int tin[maxn], low[maxn];
  49. vector<pii> stk;
  50.  
  51. vector<int> adj2[maxn];
  52.  
  53. bool dfs1(int u, int p, int s2) {
  54.     if (u == s2) return true;
  55.     for (int v : adj2[u]) {
  56.         if (v != p) {
  57.             return dfs1(v, u, s2);
  58.         }
  59.     }
  60.     return false;
  61. }
  62.  
  63. int dfs2(int u, int p, int s1, int s2, int d) {
  64.     if (u == s2) return d;
  65.     if (u == s1) return STOPSTOPSTOP;
  66.     for (int v : adj2[u]) {
  67.         if (v != p) {
  68.             return dfs2(v, u, s1, s2, d+1);
  69.         }
  70.     }
  71.     return STOPSTOPSTOP;
  72. }
  73.  
  74. void bcc_solve(int fnd1, int fnd2) {
  75.     /*
  76.     CASE 0:
  77.     just a single edge (doesn't count, skip)
  78.  
  79.     CASE 1:
  80.     normal cycle
  81.  
  82.     CASE 2:
  83.     "onion" shape
  84.     the graph looks like an onion with many layers
  85.     2 nodes have same degree (>2)
  86.     all other have degree 2
  87.     each layer is 1 or more nodes
  88.     each layer connects the 2 nodes with the big degree
  89.  
  90.     3 layers:
  91.         o - o - o
  92.       /           \
  93.     o - o - o - o - o
  94.       \           /
  95.         o - o - o
  96.     */
  97.     static int calls = 0;
  98.     ++calls;
  99.     vector<int> nodes;
  100.     int num_edges = 0, num_nodes = 0, num_2 = 0;
  101.     int special_1 = -1, special_2 = -1, special_degree_1 = -1, special_degree_2 = -2;
  102.     // cout << "BCC (fnd1=" << fnd1 << ", fnd2=" << fnd2 << ")\n";
  103.     while (true) {
  104.         int u = stk.back().first, v = stk.back().second;
  105.         for (int k : vector<int>({u, v})) {
  106.             nodes.push_back(k);
  107.             if (last[k] < calls) {
  108.                 ++num_nodes;
  109.                 last[k] = calls;
  110.                 degree[k] = 1;
  111.                 // cout << "node: " << k << "\n";
  112.             } else {
  113.                 ++degree[k];
  114.                 if (degree[k] == 2) { // 1 -> 2
  115.                     ++num_2;
  116.                 } else if (degree[k] == 3) { // 2 -> 3+
  117.                     --num_2;
  118.                     if (special_1 == -1) {
  119.                         special_1 = k;
  120.                         special_degree_1 = 3;
  121.                     } else if (special_2 == -1) {
  122.                         special_2 = k;
  123.                         special_degree_2 = 3;
  124.                     } else {
  125.                         // too many
  126.                         // cout << "(too many special)\n";
  127.                         bcc_size = STOPSTOPSTOP;
  128.                         return;
  129.                     }
  130.                 } else if (degree[k] > 3) {
  131.                     if (k == special_1) {
  132.                         ++special_degree_1;
  133.                     } else {
  134.                         ++special_degree_2;
  135.                     }
  136.                 }
  137.             }
  138.         }
  139.         // cout << "edge: " << u << "-" << v << "\n";
  140.         ++num_edges;
  141.         adj2[u].push_back(v);
  142.         adj2[v].push_back(u);
  143.         stk.pop_back();
  144.         if (stk.empty() || (u == fnd1 && v == fnd2)) {
  145.             break;
  146.         }
  147.     }
  148.     // debug(num_edges, num_nodes);
  149.     if (num_edges == 1) {
  150.         // case 0
  151.     } else if (num_edges == num_nodes) {
  152.         // case 1
  153.         if (num_2 != num_nodes || (bcc_size != NOT_FOUND && bcc_size != num_nodes)) {
  154.             bcc_size = STOPSTOPSTOP;
  155.         } else {
  156.             int src = nodes[0];
  157.             if (dfs1(adj2[src][0], -1, adj2[src][1])) {
  158.                 bcc_size = num_nodes;
  159.                 bcc_sum = (bcc_sum + num_nodes*2) % mod;
  160.             } else {
  161.                 bcc_size = STOPSTOPSTOP;
  162.             }
  163.         }
  164.     } else {
  165.         // case 2 (onion)
  166.         // debug(num_2, special_1, special_2);
  167.         // debug(special_degree_1, special_degree_2);
  168.         if (special_degree_1 != special_degree_2 || num_2 + 2 != num_nodes) {
  169.             // cout << "stop1\n";
  170.             bcc_size = STOPSTOPSTOP;
  171.         } else {
  172.             int layers = special_degree_1;
  173.             int length = -1;
  174.             for (int v : adj2[special_1]) {
  175.                 int length_here = dfs2(v, special_1, special_1, special_2, 1);
  176.                 if (length_here == STOPSTOPSTOP || (length != -1 && length != length_here)) {
  177.                     bcc_size = STOPSTOPSTOP;
  178.                     break;
  179.                 }
  180.                 length = length_here;
  181.             }
  182.             length = length*2;
  183.             // debug(length);
  184.             if (bcc_size != STOPSTOPSTOP && (bcc_size == NOT_FOUND || bcc_size == length)) {
  185.                 bcc_size = length;
  186.                 bcc_sum = (bcc_sum + (ll(layers)*(layers-1)) % mod) % mod;
  187.             } else {
  188.                 bcc_size = STOPSTOPSTOP;
  189.             }
  190.         }
  191.     }
  192.     for (int u : nodes) {
  193.         adj2[u].clear();
  194.     }
  195. }
  196.  
  197. void bcc_dfs(int u, int p) {
  198.     tin[u] = low[u] = timer++;
  199.     int children = 0;
  200.     for (int v : adj[u]) {
  201.         if (v == p) {
  202.             continue;
  203.         } else if (tin[v] != -1) {
  204.             low[u] = min(low[u], tin[v]);
  205.             if (tin[v] < tin[u]) {
  206.                 stk.emplace_back(u, v);
  207.             }
  208.         } else {
  209.             ++children;
  210.             stk.emplace_back(u, v);
  211.             bcc_dfs(v, u);  
  212.             if (bcc_size == STOPSTOPSTOP) {
  213.                 return;
  214.             }
  215.             low[u] = min(low[u], low[v]);
  216.             // the following line guarantees that we will find all BCC
  217.             if (p == -1 || (p != -1 && low[v] >= tin[u])) {
  218.                 bcc_solve(u, v);
  219.                 if (bcc_size == STOPSTOPSTOP) {
  220.                     return;
  221.                 }
  222.             }
  223.         }
  224.     }
  225. }
  226.  
  227. int main() {
  228.     ios::sync_with_stdio(false); cin.tie(0);
  229.     cin >> n >> m;
  230.     for (int i = 0; i < m; ++i) {
  231.         int a, b;
  232.         cin >> a >> b;
  233.         adj[a].push_back(b);
  234.         adj[b].push_back(a);
  235.     }
  236.     bcc_size = NOT_FOUND;
  237.     bcc_sum = 0;
  238.     timer = 0;
  239.     memset(tin, -1, sizeof(tin));
  240.     bcc_dfs(1, -1);
  241.     if (bcc_size == NOT_FOUND) {
  242.         cout << "BRAK\n";
  243.     } else if (bcc_size == STOPSTOPSTOP) {
  244.         cout << "NIE\n";
  245.     } else {
  246.         cout << "TAK\n" << bcc_size << " " << bcc_sum << "\n";
  247.     }
  248. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement