Saturday, April 4, 2020

[Codeforces] E. Fairy

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : E. Fairy
Source            : Codeforces
Category          : Graph Theory
Algorithm         : DFS Tree 
Tutorial          : https://codeforces.com/blog/entry/68138 
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll                 long long int  
  6. #define endl              '\n'  
  7.   
  8. static const int maxn = 1e5 + 5;  
  9.   
  10. struct Node  
  11. {  
  12.       int v, id;  
  13.       Node(int v = 0, int id = 0)  
  14.             : v(v), id(id) {}  
  15. };  
  16.   
  17. vector < vector <Node> > graph;  
  18. int color[maxn];  
  19. int contradictory[maxn];  
  20. int contradictoryEdges;  
  21. bool vis[maxn];  
  22. int in[maxn];  
  23. int dfsTime;  
  24. bool isBipartite;  
  25.   
  26. void dfs(int u = 1, int p = -1, int c = 0)  
  27. {  
  28.       in[u] = ++dfsTime;  
  29.       color[u] = c;  
  30.       vis[u] = 1;  
  31.       for (Node it : graph[u])  
  32.       {  
  33.             int v = it.v;  
  34.             int id = it.id;  
  35.             if (v == p) continue;  
  36.             if (vis[v] == 0)  
  37.             {  
  38.                   dfs(v, u, c ^ 1);  
  39.             }  
  40.             else if (in[v] < in[u])  
  41.             {  
  42.                   if (color[u] == color[v]) isBipartite = false, contradictory[id] = 1;  
  43.                   else contradictory[id] = 2;  
  44.             }  
  45.       }  
  46. }  
  47.   
  48. int dp1[maxn];  
  49. int dp2[maxn];  
  50. bool used[maxn];  
  51.   
  52. void solve(int u, int p = -1)  
  53. {  
  54.       used[u] = 1;  
  55.       for (Node it : graph[u])  
  56.       {  
  57.             int v = it.v;  
  58.             int id = it.id;  
  59.             if (v == p) continue;  
  60.             if (used[v] == 0)  
  61.             {  
  62.                   solve(v, u);  
  63.                   dp1[u] += dp1[v];  
  64.                   dp2[u] += dp2[v];  
  65.             }  
  66.             else if (in[v] < in[u])  
  67.             {  
  68.                   if (contradictory[id] == 1) dp1[u]++, dp1[v]--;  
  69.                   else if (contradictory[id] == 2) dp2[u]++, dp2[v]--;  
  70.             }  
  71.       }  
  72. }  
  73.   
  74. vector <int> ans;  
  75. bool visited[maxn];  
  76.   
  77. void solution(int u, int p = - 1)  
  78. {  
  79.       visited[u] = 1;  
  80.       for (Node it : graph[u])  
  81.       {  
  82.             int v = it.v;  
  83.             int id = it.id;  
  84.             if (v == p) continue;  
  85.             if (visited[v] == 0)  
  86.             {  
  87.                   if (dp1[v] == contradictoryEdges and dp2[v] == 0)  
  88.                   {  
  89.                         ans.push_back(id);  
  90.                   }  
  91.                   solution(v, u);  
  92.             }  
  93.       }  
  94. }  
  95.   
  96. signed main()  
  97. {  
  98.       ios_base::sync_with_stdio(false);  
  99.       cin.tie(nullptr);  
  100.       cout.tie(nullptr);  
  101.   
  102.       int tnode, tedge;  
  103.       cin >> tnode >> tedge;  
  104.       graph.resize(tnode + 1);  
  105.       for (int e = 1; e <= tedge; e++)  
  106.       {  
  107.             int u, v;  
  108.             cin >> u >> v;  
  109.             graph[u].emplace_back(v, e);  
  110.             graph[v].emplace_back(u, e);  
  111.       }  
  112.       int nonBipartiteComponent = 0;  
  113.       for (int i = 1; i <= tnode; i++)  
  114.       {  
  115.             if (vis[i] == 0)  
  116.             {  
  117.                   isBipartite = true;  
  118.                   dfs(i);  
  119.                   if (isBipartite == false) ++nonBipartiteComponent;  
  120.             }  
  121.       }  
  122.       if (nonBipartiteComponent == 0)  
  123.       {  
  124.             cout << tedge << endl;  
  125.             for (int i = 1; i <= tedge; i++) cout << i << " \n"[i == tedge];  
  126.             return 0;  
  127.       }  
  128.       if (nonBipartiteComponent > 2)  
  129.       {  
  130.             cout << 0 << endl;  
  131.             return 0;  
  132.       }  
  133.       for (int i = 1; i <= tedge; i++) contradictoryEdges += contradictory[i] == 1;  
  134.       for (int i = 1; i <= tnode; i++) if (used[i] == 0) solve(i);  
  135.       for (int i = 1; i <= tnode; i++) if (visited[i] == 0) solution(i);  
  136.       if (contradictoryEdges == 1) for (int i = 1; i <= tedge; i++) if (contradictory[i] == 1) ans.push_back(i);  
  137.       cout << ans.size() << endl;  
  138.       sort(ans.begin(), ans.end());  
  139.       for (int x : ans) cout << x << " ";  
  140. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.