// https://atcoder.jp/contests/abc075/tasks/abc075_c #include using namespace std; const int N = 1e5 + 10; const int M = N << 1; //链式前向星 int e[M], h[N], idx, w[M], ne[M]; void add(int a, int b, int c = 0) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; } int depth[N]; //深度 int f[N]; //用 dp[u] 来定义跨越点 u 和他的父节点的回边的数量 int res; //桥的数量 void dfs(int u) { for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (!depth[j]) { // j没有走过 depth[j] = depth[u] + 1; // 标识走过了,记录是u的下一层 dfs(j); // 深搜j,完成 f[j]的填充后返回 f[u] += f[j]; // 累加到父节点u的f[u]属性上 } else if (depth[j] < depth[u]) // u->fa[u]的回边 f[u]++; else if (depth[j] > depth[u]) //这条边子树算过了,但却不是穿过u-fa[u]的回边,需要减去 f[u]--; } f[u]--; // j-u 本身的边也被算成了回边,需要减去 //统计结果 if (depth[u] > 1 && f[u] == 0) res++; } int main() { memset(h, -1, sizeof h); int n, m; scanf("%d %d", &n, &m); for (int i = 1; i <= m; i++) { int a, b; scanf("%d %d", &a, &b); add(a, b), add(b, a); } //将1视为树根,进行搜索 depth[1] = 1; dfs(1); printf("%d\n", res); return 0; }