Korotkodul

Задача D. Компоненты вершинной двусвязности

Oct 19th, 2021 (edited)
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.21 KB | None | 0 0
  1. #include <vector>
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <map>
  5. using namespace std;
  6.  
  7. vector <int> tin;
  8. vector <int> up;
  9. vector <bool> was;
  10. vector <vector<int>> gr;
  11. vector <bool> cut_p;
  12. int P = 0;
  13. vector <bool> root;
  14. vector <bool> connected;
  15. void dfs(int v, int last, int timer) {
  16.     was[v] = true;
  17.     tin[v] = up[v] = timer;
  18.  
  19.     int child = 0;
  20.     for (int u : gr[v]) {
  21.  
  22.         if (u == last) {
  23.  
  24.             continue;
  25.         }
  26.         else if (was[u] == true) {
  27.  
  28.             up[v] = min(up[v], tin[u]);
  29.         }
  30.         else if (was[u] == false) {
  31.             dfs(u, v, timer + 1);
  32.             up[v] = min(up[v], up[u]);
  33.             if (up[u] >= tin[v] && v != last) {
  34.                 if (!cut_p[v]) P++;
  35.                 cut_p[v] = true;
  36.             }
  37.             child++;
  38.         }
  39.     }
  40.     if (v == last && child > 1) {
  41.         if (!cut_p[v]) P++;
  42.         cut_p[v] = true;
  43.         root[v] = true;
  44.     }
  45.  
  46. }
  47.  
  48. bool cp(int v, int u) {//check that (v) is cut_point
  49.     if (up[u] >= tin[v]) {
  50.         return true;
  51.     }
  52.     else {
  53.         return false;
  54.     }
  55. }
  56.  
  57.  
  58. int max_col = 0;
  59. int cnt;
  60. map < pair<int, int>, int> marker;
  61. void mark(int v, int last, int color, int cnt) {
  62.     //cout << "V in = " << v + 1 << '\n';
  63.     was[v] = true;
  64.     for (int u : gr[v]) {
  65.         //cout << "(" << v + 1 << "," << u + 1 << ")" << '\n';
  66.         if (u == last) {
  67.             //cout << "skip\n";
  68.             continue;
  69.         }
  70.         else if (!was[u]) {
  71.             if (cut_p[v] && cp(v, u)) {
  72.                 //cout << "ONE\n";
  73.                 if (!(root[v] && cnt == 0)) {
  74.                     max_col++;
  75.                 }
  76.                 cnt++;
  77.                 marker[{min(u, v), max(u, v)}] = max_col;
  78.                 //cout << "marker[{min(u, v), max(u, v)}] = " << marker[{min(u, v), max(u, v)}] << '\n';
  79.                 //cout << "max_col = " << max_col << '\n';
  80.                 mark(u, v, max_col, cnt);
  81.             }
  82.             else {
  83.                 //cout << "TWO\n";
  84.                 marker[{min(u, v), max(u, v)}] = color;
  85.                 //cout << "color = " << color << '\n';
  86.                 mark(u, v, color, cnt);
  87.             }
  88.         }
  89.         else if (was[u] && tin[v] > tin[u]) {
  90.             //cout << "(" << v + 1 << "," << u + 1 << ")" << '\n';
  91.             //cout << "THREE\n";
  92.             //cout << "color = " << color << '\n';
  93.             marker[{min(u, v), max(u, v)}] = color;
  94.         }
  95.     }
  96. }
  97.  
  98.  
  99. int main()
  100. {
  101.     int n, m;
  102.     cin >> n >> m;
  103.     gr.resize(n);
  104.     cut_p.resize(n, false);
  105.     connected.resize(n, false);
  106.     vector <pair <int, int> > Edges;
  107.     root.resize(n, false);
  108.     for (int i = 0; i < m; ++i) {
  109.         int a, b;
  110.         cin >> a >> b;
  111.         a--;
  112.         b--;
  113.         gr[a].push_back(b);
  114.         gr[b].push_back(a);
  115.         connected[a] = true;
  116.         connected[b] = true;
  117.         Edges.push_back({ min(a,b), max(a,b) });
  118.         marker[{ min(a, b), max(a, b) }] = -999;
  119.     }
  120.     tin.resize(n, -4);
  121.     up.resize(n, 1e9);
  122.     was.resize(n, false);
  123.     for (int i = 0; i < n; ++i) {
  124.         if (was[i] || !connected[i]) continue;
  125.         dfs(i, i, 0);
  126.     }
  127.     /*cout << "\ntin\n";
  128.     for (int i = 0;i<n;++i){
  129.         cout<<i+1<<": "<<tin[i]<<'\n';
  130.     }cout<<'\n';
  131.     cout<<"up\n";
  132.     for (int i=0;i<n;++i){
  133.         cout<<i+1<<": "<<up[i]<<'\n';
  134.     }cout<<'\n';
  135.     cout <<"amount of cut_points = "<< P<< '\n';
  136.     cout << "points:\n";
  137.     for (int i= 0;i<n;++i){
  138.         if (cut_p[i]){
  139.             cout<<i+1<<'\n';
  140.         }
  141.     }*/
  142.     //cout << "ROOT = " << root << '\n';
  143.     was.assign(n, false);
  144.     //cout << "GO MARKING\n";
  145.     for (int i = 0; i < n; ++i) {
  146.         if (was[i] || !connected[i]) continue;
  147.         max_col++;
  148.         //cout << "i = " << i << "  max_col = " << max_col << '\n';
  149.         cnt = 0;
  150.         mark(i, i, max_col, cnt);
  151.     }
  152.     //cout<<"num of components = "<<max_col<<'\n';
  153.     //cout << "\marker\n";
  154.     cout << max_col << '\n';
  155.     for (auto x : Edges) {
  156.         //cout<<"("<<x.first+1<<","<<x.second+1<<")="<<marker[x]<<'\n';
  157.         cout << marker[x] << ' ';
  158.     }
  159. }
  160. /*
  161. 5 5
  162. 1 2
  163. 1 3
  164. 3 4
  165. 2 4
  166. 5 4
  167. */
  168. /*
  169. 3 2
  170. 1 2
  171. 1 3
  172. */
  173. /*
  174. 4 3
  175. 1 2
  176. 1 3
  177. 1 4
  178. */
Add Comment
Please, Sign In to add comment