为什么这篇没人写题解呢,去网上查了半天找到的还大多数是链式前向星建图的。 这题应该算是一个边双连通分量的板子吧,我们首先进行点双连通分量缩点,缩点后的图是一片森林,如果原图连通那么就是一棵树,若想整张图点双连通我们记所有度为的点个数为,最少添加的边数为但我们发现tarjan跑有向图一点问题都没有,跑无向图时可能会走回头路,所以我们使用一个神奇的操作,即异或上一个1的操作,我们把正边记为,反边记为这样判断的时候就可以判断这条边是否走过。具体实现看代码有什么问题欢迎大家私聊讨论

#include<bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;

std::stack<int> st;
std::vector<std::pair<int, int> > e[500005];
std::vector<std::vector<int> > ans;
int dfn[500005], low[500005], vis[500005], col[500005], du[500005];
int cnt = 0, num = 0;

void tarjan(int u, int f) {
    dfn[u] = low[u] = ++ cnt;
    vis[u] = 1;
    st.push(u);

    for (auto [v, las] : e[u]) {
        if (las == (f ^ 1)) continue;//这里即为判断该边是否走过
        if (!dfn[v]) {
            tarjan(v, las);
            low[u] = std::min(low[u], low[v]);
        }
        else {
            low[u] = std::min(low[u], dfn[v]);
        }
    }
    
    if (dfn[u] == low[u]) {
        std::vector<int> vec;
        num++;
        while (1) {
            int cur = st.top();
            vec.push_back(cur);
            st.pop();
            col[cur] = num;
            vis[cur] = 0;
            if (cur == u) break;
        }
        ans.push_back(vec);
    }
}

void solve() {
    int n, m;
    std::cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v;
        std::cin >> u >> v;
        e[u].push_back({v, i << 1});
        e[v].push_back({u, i << 1 | 1});
    }

    for (int i = 1; i <= n; i++) {
        if (!dfn[i]) {
            tarjan(i, -1);
        }
    }

    for (int i = 1; i <= n; i++) {
        for (auto [v, lat] : e[i]) {
            int x = col[i], y = col[v];
            if (x != y) {
                du[y]++;//由于是无向图,如果给两个点的度都加一的话“叶子”节点的度就为2了,所以我这里只给y加了一个度。
            }
        }
    }

    int ans = 0;
    for (int i = 1; i <= num; i++) {
        if (du[i] == 1) {
            ans++;
        }
    }

    std::cout << (ans + 1) / 2 << '\n';
}

signed main() {
    std::ios::sync_with_stdio(0);
    std::cout.tie(0);
    std::cin.tie(0);
    i64 t = 1; 
    // std::cin >> t;
    while (t--) {
        solve();
    }
}