Advertisement
Mlxa

### Поиск треугольников в графе

Jan 22nd, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.40 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. typedef long double ld;
  5. #define long ll
  6. #define double ld
  7. #define all(x) begin(x), end(x)
  8.  
  9. const int N = 3e5;
  10. vector<int> g[N];
  11. vector<int> r[N];
  12. int deg[N];
  13. int n, m, k;
  14.  
  15. inline bool deg_cmp(int a, int b) {
  16.     if (deg[a] != deg[b]) {
  17.         return deg[a] < deg[b];
  18.     }
  19.     return a < b;
  20. }
  21.  
  22. int cyc_used[N];
  23.  
  24. vector<vector<int>> cycles;
  25.  
  26. void check_triangle(int a, int b, int c) {
  27.     //cerr << a << ' ' << b << ' ' << c << endl;
  28.     if (cyc_used[a] || cyc_used[b] || cyc_used[c]) {
  29.         return;
  30.     }
  31.     vector<int> temp;
  32.     for (int i = 0, d = min((int)g[a].size(), 3); i < d; ++i) {
  33.         if (g[a][i] != b && g[a][i] != c) {
  34.             temp.push_back(g[a][i]);
  35.         }
  36.     }
  37.     for (int i = 0, d = min((int)g[b].size(), 3); i < d; ++i) {
  38.         if (g[b][i] != a && g[a][i] != c) {
  39.             temp.push_back(g[b][i]);
  40.         }
  41.     }
  42.     for (int i = 0, d = min((int)g[c].size(), 3); i < d; ++i) {
  43.         if (g[c][i] != a && g[c][i] != b) {
  44.             temp.push_back(g[c][i]);
  45.         }
  46.     }
  47.     sort(temp.begin(), temp.end(), deg_cmp);
  48.     for (int i : temp) {
  49.         if (!cyc_used[i]) {
  50.             vector<int> tt = { i, a, b, c };
  51.             for (int p = 0; p < 4; ++p) {
  52.                 if (!cyc_used[tt[p]]) {
  53.                     swap(tt[0], tt[p]);
  54.                 }
  55.             }
  56.             if (!cyc_used[tt[0]]) {
  57.                 cycles.push_back(tt);
  58.                 cyc_used[tt[0]]=  true;
  59.                 cyc_used[tt[1]]=  true;
  60.                 cyc_used[tt[2]]=  true;
  61.                 cyc_used[tt[3]]=  true;
  62.             }
  63.            
  64.         }
  65.     }
  66. }
  67.  
  68. void read_input() {
  69. #ifdef LC
  70.     assert(freopen("input.txt", "r", stdin));
  71. #endif
  72.     ios::sync_with_stdio(false);
  73.     cin.tie(nullptr);
  74.     cin >> n >> m >> k;
  75.     for (int a, b, i = 0; i < m; ++i) {
  76.         cin >> a >> b;
  77.         --a;
  78.         --b;
  79.         g[a].push_back(b);
  80.         g[b].push_back(a);
  81.         ++deg[a];
  82.         ++deg[b];
  83.     }
  84. }
  85.  
  86. void find_triangles() {
  87.     for (int i = 0; i < n; ++i) {
  88.         for (int j : g[i]) {
  89.             if (deg_cmp(i, j)) {
  90.                 r[i].push_back(j);
  91.             }
  92.         }
  93.         sort(r[i].begin(), r[i].end(), deg_cmp);
  94.     }
  95.     for (int i = 0; i < n; ++i) {
  96.         for (int j : r[i]) {
  97.             auto a = r[i].begin();
  98.             auto b = r[j].begin();
  99.             while (a != r[i].end() && b != r[j].end()) {
  100.                 if (*a == *b) {
  101.                     check_triangle(i, j, *a);
  102.                     ++a;
  103.                     ++b;
  104.                 } else if (deg_cmp(*a, *b)) {
  105.                     ++a;
  106.                 } else {
  107.                     ++b;
  108.                 }
  109.             }
  110.         }
  111.     }
  112. }
  113.  
  114. int used[N], cur_used = 0;
  115. int dist[N];
  116. int pr[N];
  117. int path[N], path_p;
  118.  
  119.  
  120. void dfs(int v, int len) {
  121.     ++cur_used;
  122.     pr[v] = N - 1;
  123.     dist[v] = 1;
  124.     used[v] = cur_used;
  125.     path_p = 0;
  126.     path[path_p++] = v;
  127.     while (path_p > 0) {
  128.         v = path[--path_p];
  129.         assert(used[v] == cur_used);
  130.         if (dist[v] >= len) {
  131.             cout << "PATH\n";
  132.             vector<int> pt;
  133.             int x = v;
  134.             while (used[x] >= cur_used) {
  135.                 pt.push_back(x);
  136.                 x = pr[x];
  137.             }
  138.             reverse(all(pt));
  139.             cout << pt.size() << '\n';
  140.             for (auto e : pt) {
  141.                 cout << e + 1 << ' ';
  142.             }
  143.             cout << '\n';
  144.             exit(0);               
  145.         }
  146.         for (int u : g[v]) {
  147.             if (used[u] < cur_used) {
  148.                 path[path_p++] = u;
  149.                 dist[u] = dist[v] + 1;
  150.                 used[u] = cur_used;
  151.                 pr[u] = v;
  152.             }
  153.         }
  154.     }
  155. }
  156.  
  157. int main() {
  158.     read_input();
  159.     find_triangles();
  160.     if ((int)cycles.size() >= k) {
  161.         cout << "CYCLES\n";
  162.         for (int i = 0; i < k; ++i) {
  163.             cout << cycles[i].size() << '\n';
  164.             for (int e : cycles[i]) {
  165.                 cout << e + 1 << ' ';
  166.             }
  167.             cout << '\n';
  168.         }
  169.         return 0;
  170.     }
  171.     mt19937 randint;
  172.     while (clock() < 0.95 * CLOCKS_PER_SEC) {
  173.         int i = (int)(randint() % (size_t)n);
  174.         dfs(i, (n + k - 1) / k);
  175.     }
  176.     cout << "-1\n";
  177.     return 0;
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement