Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- int n, m, timer;
- std::vector< std::vector<int> > adj;
- std::vector< std::vector<int> > comp_sizes; // size of components
- std::vector< int > tin, fup;
- std::vector< bool > visited;
- void dfs(int v, int p)
- {
- visited[v] = true;
- tin[v] = fup[v] = timer++;
- int children = 0;
- for(auto u: adj[v])
- {
- if (u == p) continue; // skip parent
- if (visited[u])
- { // back edge
- fup[v] = std::min(fup[v], tin[u]);
- }
- else
- {
- int cnt1 = timer; // count vertex before U
- dfs(u, v);
- int cnt2 = timer; // count vertex after U
- fup[v] = std::min(fup[v], fup[u]);
- ++children;
- if ((fup[u] >= tin[v] && p != 0) || (p == 0 && children > 1))
- { // vertex V cut graph: components that start from U has size (cnt2 - cnt1)
- comp_sizes[v].push_back(cnt2 - cnt1);
- }
- }
- }
- }
- int main()
- {
- std::ios_base::sync_with_stdio(0);
- std::cin.tie(0);
- std::cout.tie(0);
- #ifdef AZHUKOV
- freopen("input.txt", "r", stdin);
- #endif // AZHUKOV
- std::cin >> n >> m;
- adj.resize(n + 1, std::vector<int>() );
- comp_sizes.resize(n + 1, std::vector<int>() );
- tin.resize(n + 1, 0); // time input
- fup.resize(n + 1, 0); // min time out to up in subtree
- visited.resize(n + 1, false);
- for(int i = 0; i < m; ++i)
- {
- int v_from, v_to;
- std::cin >> v_from >> v_to;
- adj[v_from].push_back(v_to);
- adj[v_to].push_back(v_from);
- }
- timer = 1;
- dfs(1, 0); // parent = 0 - without parent
- // calc answer
- for(int v = 1; v<= n; ++v)
- {
- int ans = n - 1; // for each vertex V: V - U
- int t = n - 1;
- for(const int & x: comp_sizes[v])
- {
- t -= x;
- assert(t >= 0);
- ans += t * x;
- }
- std::cout << ans << std::endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement