Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // I'm the bone of my code. Syntax is my body, data is my blood ...
- #include<bits/stdc++.h>
- #define FILE "khistory"
- using namespace std;
- const int N = 1e5 + 10;
- int n, m;
- vector<int > adj[N], tree[N];
- pair<int, int > edg[N];
- int num[N], low[N], timer;
- struct DSU
- {
- int par[N], num[N];
- DSU()
- {
- memset(par, 0, sizeof par);
- for (int i = 0; i < N; i++) num[i] = 1;
- }
- int anc(int u)
- { return (par[u] == 0 ? u : par[u] = anc(par[u])); }
- void add(int u, int v)
- {
- if ( (u = anc(u)) == (v = anc(v)) ) return;
- if (num[u] < num[v]) swap(u, v);
- par[v] = u;
- num[u] += num[v];
- }
- } dsu;
- void dfs(int u, int dady)
- {
- num[u] = low[u] = ++timer;
- for (int v : adj[u])
- {
- if ( v == dady ) continue;
- if (num[v]) low[u] = min(low[u], num[v]);
- else
- {
- dfs(v, u);
- low[u] = min(low[u], low[v]);
- if (low[v] >= num[v]) ;
- else dsu.add(u, v);
- }
- }
- }
- void init()
- {
- for (int i = 1; i <= n; i++)
- if (!num[i]) dfs(i, i);
- for (int i = 1; i <= m; i++)
- {
- int au = dsu.anc(edg[i].first), av = dsu.anc(edg[i].second);
- if (au == av) continue;
- tree[au].push_back(av);
- tree[av].push_back(au);
- }
- }
- int dp[N][2][2];
- bool mark[N];
- void dfs_tree(int u, int dady)
- {
- mark[u] = 1;
- dp[u][1][1] = (dady == u ? n + 10 : 1), dp[u][1][0] = (dady == u ? n + 10 : 0);
- dp[u][0][1] = 1, dp[u][0][0] = 0;
- int sum = 0, sum1 = 0;
- int best = -1;
- bool isLeaf = 0;
- for (int v : tree[u])
- {
- if (v == dady) continue;
- isLeaf = 1;
- dfs_tree(v, u);
- sum1 += min(dp[v][1][0], dp[v][1][1]);
- int x = min(dp[v][0][1], dp[v][0][0]);
- sum += x;
- best = (best == -1 ? dp[v][0][1] - x : min(best, dp[v][0][1] - x));
- }
- if (!isLeaf)
- {
- dp[u][0][0] = n + 10;
- return;
- }
- dp[u][1][1] += sum1;
- dp[u][1][0] += sum;
- dp[u][0][1] += sum1;
- dp[u][0][0] += sum + best;
- }
- void solve()
- {
- int ans = 0;
- for (int ix = 1; ix <= n; ix++)
- {
- int i = dsu.anc(ix);
- if (!mark[i])
- dfs_tree(i, i),
- ans += min(dp[i][0][1], dp[i][0][0]);
- }
- cout << ans << '\n';
- }
- int main()
- {
- if (fopen("main.in", "r"))
- assert(freopen("main.in", "r", stdin));
- else
- if (fopen(FILE".inp", "r"))
- assert(freopen(FILE".inp", "r", stdin)),
- assert(freopen(FILE".out", "w", stdout));
- ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
- cin >> n >> m;
- for (int i = 1; i <= m; i++)
- {
- int x, y;
- cin >> x >> y;
- edg[i] = {x, y};
- adj[x].push_back(y);
- adj[y].push_back(x);
- }
- init();
- solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement