Advertisement
JermPeoria

Untitled

Dec 1st, 2018
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
R 2.37 KB | None | 0 0
  1. // I'm the bone of my code. Syntax is my body, data is my blood ...
  2. #include<bits/stdc++.h>
  3. #define FILE "khistory"
  4. using namespace std;
  5.  
  6. const int N = 1e5 + 10;
  7.  
  8. int n, m;
  9. vector<int > adj[N], tree[N];
  10. pair<int, int > edg[N];
  11. int num[N], low[N], timer;
  12.  
  13. struct DSU
  14. {
  15.     int par[N], num[N];
  16.     DSU()
  17.     {
  18.         memset(par, 0, sizeof par);
  19.         for (int i = 0; i < N; i++) num[i] = 1;
  20.     }
  21.  
  22.     int anc(int u)
  23.     { return (par[u] == 0 ? u : par[u] = anc(par[u])); }
  24.  
  25.     void add(int u, int v)
  26.     {
  27.         if ( (u = anc(u)) == (v = anc(v)) ) return;
  28.         if (num[u] < num[v]) swap(u, v);
  29.         par[v] = u;
  30.         num[u] += num[v];
  31.     }
  32.  
  33. } dsu;
  34.  
  35. void dfs(int u, int dady)
  36. {
  37.     num[u] = low[u] = ++timer;
  38.     for (int v : adj[u])
  39.     {
  40.         if ( v == dady ) continue;
  41.         if (num[v]) low[u] = min(low[u], num[v]);
  42.         else
  43.         {
  44.             dfs(v, u);
  45.             low[u] = min(low[u], low[v]);
  46.             if (low[v] >= num[v]) ;
  47.             else dsu.add(u, v);
  48.         }
  49.     }
  50. }
  51.  
  52. void init()
  53. {
  54.     for (int i = 1; i <= n; i++)
  55.         if (!num[i]) dfs(i, i);
  56.     for (int i = 1; i <= m; i++)
  57.     {
  58.         int au = dsu.anc(edg[i].first), av = dsu.anc(edg[i].second);
  59.         if (au == av) continue;
  60.         tree[au].push_back(av);
  61.         tree[av].push_back(au);
  62.     }
  63. }
  64.  
  65. int dp[N][2][2];
  66. bool mark[N];
  67.  
  68. void dfs_tree(int u, int dady)
  69. {
  70.     mark[u] = 1;
  71.  
  72.     dp[u][1][1] = (dady == u ? n + 10 : 1), dp[u][1][0] = (dady == u ? n + 10 : 0);
  73.     dp[u][0][1] = 1, dp[u][0][0] = 0;
  74.  
  75.     int sum = 0, sum1 = 0;
  76.     int best = -1;
  77.     bool isLeaf = 0;
  78.  
  79.     for (int v : tree[u])
  80.     {
  81.         if (v == dady) continue;
  82.  
  83.         isLeaf = 1;
  84.         dfs_tree(v, u);
  85.         sum1 += min(dp[v][1][0], dp[v][1][1]);
  86.         int x = min(dp[v][0][1], dp[v][0][0]);
  87.         sum += x;
  88.         best = (best == -1 ? dp[v][0][1] - x : min(best, dp[v][0][1] - x));
  89.     }
  90.     if (!isLeaf)
  91.     {
  92.         dp[u][0][0] = n + 10;
  93.         return;
  94.     }
  95.     dp[u][1][1] += sum1;
  96.     dp[u][1][0] += sum;
  97.     dp[u][0][1] += sum1;
  98.     dp[u][0][0] += sum + best;
  99.  
  100. }
  101.  
  102. void solve()
  103. {
  104.     int ans = 0;
  105.     for (int ix = 1; ix <= n; ix++)
  106.     {
  107.         int i = dsu.anc(ix);
  108.         if (!mark[i])
  109.             dfs_tree(i, i),
  110.             ans += min(dp[i][0][1], dp[i][0][0]);
  111.     }
  112.  
  113.     cout << ans << '\n';
  114. }
  115.  
  116. int main()
  117. {
  118.     if (fopen("main.in", "r"))
  119.         assert(freopen("main.in", "r", stdin));
  120.     else
  121.     if (fopen(FILE".inp", "r"))
  122.         assert(freopen(FILE".inp", "r", stdin)),
  123.         assert(freopen(FILE".out", "w", stdout));
  124.  
  125.    
  126.     ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  127.     cin >> n >> m;
  128.     for (int i = 1; i <= m; i++)
  129.     {
  130.         int x, y;
  131.         cin >> x >> y;
  132.         edg[i] = {x, y};
  133.         adj[x].push_back(y);
  134.         adj[y].push_back(x);
  135.     }
  136.  
  137.     init();
  138.     solve();
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement