Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <iostream>
- #include <array>
- #include <vector>
- #include <numeric>
- #include <random>
- #include <chrono>
- #include <set>
- #include <map>
- #include <queue>
- #define int long long
- using namespace std;
- const long long INF = 1e9 + 7;
- const int MAXN = 1e5 + 1000;
- const int N = 1e5 + 10;
- vector<vector<pair<int, int>>> g;
- vector<vector<int>> tree;
- array<int, MAXN> used, tin, up, color;
- int timer = 0;
- set<int> bridge;
- map<int, pair<int, int>> decompress;
- void dfs(int v, int e = -1) {
- used[v] = true;
- tin[v] = up[v] = timer++;
- for (auto [to, num]: g[v]) {
- if (num == e) {
- continue;
- }
- if (used[to]) {
- up[v] = min(up[v], tin[to]);
- } else {
- dfs(to, num);
- up[v] = min(up[v], up[to]);
- if (up[to] > tin[v]) {
- bridge.insert(num);
- }
- }
- }
- }
- int col = 0;
- void paint(int v) {
- used[v] = true;
- color[v] = col;
- for (auto [to, num]: g[v]) {
- if (bridge.contains(num)) {
- continue;
- }
- if (!used[to]) {
- paint(to);
- }
- }
- }
- inline void solve() {
- int n, m;
- cin >> n >> m;
- g.clear();
- g.resize(n);
- for (int i = 0; i < m; ++i) {
- int u, v;
- cin >> u >> v;
- --u, --v;
- g[u].emplace_back(v, i);
- g[v].emplace_back(u, i);
- decompress[i] = {u, v};
- }
- used.fill(0); // нахождение мостов
- tin.fill(0);
- up.fill(0);
- bridge.clear();
- timer = 0;
- for (int i = 0; i < n; ++i) {
- if (!used[i]) {
- dfs(i);
- }
- }
- used.fill(0); // раскраска компонент без мостов
- color.fill(0);
- col = 0;
- for (int i = 0; i < n; ++i) {
- if (!used[i]) {
- paint(i);
- ++col;
- }
- }
- tree.clear(); // построение дерева
- tree.resize(n);
- for (auto& i: bridge) {
- auto [u, v] = decompress[i];
- u = color[u];
- v = color[v];
- tree[u].emplace_back(v);
- tree[v].emplace_back(u);
- }
- vector<int> d(col, -1);
- queue<int> q;
- d[0] = 0;
- q.push(0);
- int max_dist = 0;
- while (!q.empty()) {
- int v = q.front();
- q.pop();
- for (auto to: tree[v]) {
- if (d[to] == -1) {
- d[to] = d[v] + 1;
- q.push(to);
- }
- if (d[to] > d[max_dist]) {
- max_dist = to;
- }
- }
- }
- fill(d.begin(), d.end(), -1);
- int start = max_dist;
- d[start] = 0;
- q.push(start);
- while (!q.empty()) {
- int v = q.front();
- q.pop();
- for (auto to: tree[v]) {
- if (d[to] == -1) {
- d[to] = d[v] + 1;
- q.push(to);
- }
- if (d[to] > d[max_dist]) {
- max_dist = to;
- }
- }
- }
- cout << bridge.size() - d[max_dist] << '\n';
- }
- signed main() {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- int tt = 1;
- cin >> tt;
- while (tt--) {
- solve();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment