Advertisement
TrickmanOff

Informatics #889 stress

Aug 17th, 2020
2,206
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.99 KB | None | 0 0
  1. //#pragma optimization_level 3
  2. //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
  3. //#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
  4. #include <iostream>
  5. #include <algorithm>
  6. #include <fstream>
  7. #include <vector>
  8. #include <queue>
  9. #include <functional>
  10. #include <set>
  11. #include <map>
  12. #include <math.h>
  13. #include <cmath>
  14. #include <string>
  15. #include <random>
  16. #include <unordered_set>
  17. #include <unordered_map>
  18. #include <bitset>
  19. #include <string.h>
  20. #include <stack>
  21. #include <assert.h>
  22. #include <list>
  23. #include <time.h>
  24. #include <memory>
  25. #include <chrono>
  26. using namespace std;
  27. //
  28. //#define LOGGING
  29. #define fast cin.tie(0);cout.tie(0);cin.sync_with_stdio(0);cout.sync_with_stdio(0);
  30. //#define cin in
  31. //#define cout out
  32. #define ll long long
  33. #define db double
  34. #define ld long double
  35. #define uset unordered_set
  36. #define umap unordered_map
  37. #define ms multiset
  38. #define pb push_back
  39. #define pq priority_queue
  40. #define umap unordered_map
  41. #define uset unordered_set
  42. #define ull unsigned long long
  43. #define pii pair<int, int>
  44. #define pll pair<ll, ll>
  45. #define pdd pair<ld, ld>
  46. #define pnn pair<Node*, Node*>
  47. #define uid uniform_int_distribution
  48. #define PI acos(-1.0)
  49. //#define sort(a, b) sort(a.begin(), a.end(), b())
  50. //mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
  51. ifstream in("input.txt");
  52. ofstream out("output.txt");
  53.  
  54. const int MAX_N = 1e5;
  55.  
  56. struct pth {
  57.     int u1, u2, last;
  58. };
  59.  
  60. int maxd[MAX_N], sub_path[MAX_N], path1[MAX_N];
  61. int _maxd[MAX_N];
  62. pii _sub_path[MAX_N];
  63. pth _path1[MAX_N];
  64.  
  65. vector<int> g[MAX_N], ch[MAX_N];
  66. int n;
  67.  
  68. int ans = 0;
  69. pii path[2];
  70.  
  71. bool vis[MAX_N];
  72. void find_maxi_cycle(int st, int v, int len, int &max_len) {
  73.     vis[v] = 1;
  74.  
  75.     for (int to : g[v]) {
  76.         if (to == st)
  77.             max_len = max(max_len, len);
  78.  
  79.         if (!vis[to])
  80.             find_maxi_cycle(st, to, len + 1, max_len);
  81.     }
  82.  
  83.     vis[v] = 0;
  84. }
  85.  
  86. int find_maxi_cycle() {
  87.     int max_len = 0;
  88.     for (int v = 0; v < n; v++)
  89.         find_maxi_cycle(v, v, 1, max_len);
  90.     return max_len;
  91. }
  92.  
  93. template<typename T>
  94. void upd(int& val, int upd, T& pr, const T& cur_pr) {
  95.     if (upd > val) {
  96.         val = upd;
  97.         pr = cur_pr;
  98.     }
  99. }
  100.  
  101. void upd_ans(int upd, pii a, pii b) {
  102.     if (upd > ans) {
  103.         ans = upd;
  104.         path[0] = a;
  105.         path[1] = b;
  106.     }
  107. }
  108.  
  109. void upd_ans(int upd, pii a) {
  110.     if (upd > ans) {
  111.         ans = upd;
  112.         path[0] = a;
  113.         path[1] = { -1, -1 };
  114.     }
  115. }
  116.  
  117. void calc(int v) {
  118.     upd(maxd[v], 1, _maxd[v], v);
  119.  
  120.     //calculates dp values
  121.     for (int to : ch[v]) {
  122.         calc(to);
  123.  
  124.         //maxd
  125.         upd(maxd[v], maxd[to] + 1, _maxd[v], _maxd[to]);
  126.  
  127.         //sub_path
  128.         upd(sub_path[v], sub_path[to], _sub_path[v], _sub_path[to]);
  129.  
  130.         //path1
  131.         upd(path1[v], path1[to] + 1, _path1[v], _path1[to]);
  132.     }
  133.  
  134.     //update sub_path[v]
  135.     upd(sub_path[v], maxd[v], _sub_path[v], { v, _maxd[v] });
  136.     sort(ch[v].begin(), ch[v].end(), [&](const int a, const int b) {return maxd[a] > maxd[b]; });
  137.     if (ch[v].size() >= 2)
  138.         upd(sub_path[v], maxd[ch[v][0]] + maxd[ch[v][1]] + 1, _sub_path[v], { _maxd[ch[v][0]], _maxd[ch[v][1]] });
  139.  
  140.     //update ans with 1 added edge
  141.     upd_ans(maxd[v], { v, _maxd[v] });
  142.     if (ch[v].size() >= 2)
  143.         upd_ans(maxd[ch[v][0]] + maxd[ch[v][1]] + 1, { _maxd[ch[v][0]], _maxd[ch[v][1]] });
  144.    
  145.     //upate ans with 2 added edges
  146.     if (ch[v].size() >= 2) {
  147.         for (int i = 0; i < ch[v].size(); ++i) {
  148.             int u1 = ch[v][i];
  149.             int u2 = (i == 0 ? ch[v][1] : ch[v][0]);
  150.             upd_ans(path1[u1] + maxd[u2] + 1, { _path1[u1].u1, _path1[u1].u2 }, { _path1[u1].last, _maxd[u2] });
  151.         }
  152.     }
  153.     if (ch[v].size() >= 3) {
  154.         for (int i = 0; i < ch[v].size(); ++i) {
  155.             int u2 = ch[v][i];
  156.             int u1 = (i == 0 ? ch[v][1] : ch[v][0]);
  157.             int u3 = (i <= 1 ? ch[v][2] : ch[v][1]);
  158.             upd_ans(maxd[u1] + sub_path[u2] + maxd[u3] + 1, { _maxd[u1], _sub_path[u2].first },
  159.                 { _sub_path[u2].second, _maxd[u3] });
  160.         }
  161.     }
  162.  
  163.     //update path1[v]
  164.     if (ch[v].size() >= 2) {
  165.         for (int i = 0; i < ch[v].size(); i++) {
  166.             int maxi_to = ch[v][!i];
  167.             int to = ch[v][i];
  168.  
  169.             pth cur = {_maxd[maxi_to], _sub_path[to].first, _sub_path[to].second};
  170.             upd(path1[v], maxd[maxi_to] + sub_path[to] + 1, _path1[v], cur);
  171.         }
  172.     }
  173.  
  174.     //upate ans with 2 added edges
  175.     if (ch[v].size() >= 1)
  176.         upd_ans(path1[v], { _path1[v].u1, _path1[v].u2 }, { _path1[v].last, v });
  177. }
  178.  
  179. void dfs(int v, int pr) {
  180.     for (int to : g[v]) {
  181.         if (to == pr) continue;
  182.         ch[v].push_back(to);
  183.  
  184.         dfs(to, v);
  185.     }
  186. }
  187.  
  188. void input() {
  189.     cin >> n;
  190.     for (int i = 0; i < n - 1; ++i) {
  191.         int a, b;
  192.         cin >> a >> b;
  193.         --a; --b;
  194.         g[a].push_back(b);
  195.         g[b].push_back(a);
  196.     }
  197. }
  198.  
  199. void rand_gen() {
  200.     for (int i = 0; i < MAX_N; i++) {
  201.         g[i].clear();
  202.         ch[i].clear();
  203.     }
  204.     ans = 0;
  205.     memset(maxd, 0, sizeof(maxd));
  206.     memset(path1, 0, sizeof(path1));
  207.     memset(sub_path, 0, sizeof(sub_path));
  208.  
  209.     n = 50;
  210.  
  211.     for (int v = 1; v < n; v++) {
  212.         int p = rand() % v;
  213.         g[p].push_back(v);
  214.         g[v].push_back(p);
  215.     }
  216. }
  217.  
  218. int main() {
  219.     //input();
  220.     srand(time(0));
  221.     for (int cnt = 0;; ++cnt) {
  222.         if (cnt && (cnt % 1000 == 0)) cout << '=';
  223.         rand_gen();
  224.  
  225.         dfs(0, -1);
  226.  
  227.         calc(0);
  228.  
  229.         g[path[0].first].push_back(path[0].second);
  230.         g[path[0].second].push_back(path[0].first);
  231.         assert(path[0].first >= 0 && path[0].first < n);
  232.         assert(path[0].second >= 0 && path[0].second < n);
  233.         if (path[1].first != -1) {
  234.             assert(path[1].first >= 0 && path[1].first < n);
  235.             assert(path[1].second >= 0 && path[1].second < n);
  236.             g[path[1].first].push_back(path[1].second);
  237.             g[path[1].second].push_back(path[1].first);
  238.         }
  239.  
  240.         int real_max_cycle = find_maxi_cycle();
  241.         //cout << real_max_cycle << '\n';
  242.         if (real_max_cycle != ans) {
  243.             cout << '\n';
  244.  
  245.             cout << "real: " << real_max_cycle << '\n' <<
  246.                 "ans: " << ans;
  247.            
  248.             cout << n << '\n';
  249.             for (int v = 0; v < n; v++) {
  250.                 cout << v << ": ";
  251.                 for (int u : ch[v]) cout << u << ' ';
  252.                 cout << '\n';
  253.             }
  254.             break;
  255.         }
  256.     }
  257.     /*
  258.  
  259.     cout << ans << '\n';
  260.     cout << path[0].first + 1 << ' ' << path[0].second + 1;
  261.     if (path[1].first != -1)
  262.         cout << '\n' << path[1].first + 1 << ' ' << path[1].second + 1;
  263.         */
  264. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement