【题目链接】
【算法】
tarjan算法求边双联通分量
【代码】
#include <algorithm> #include <bitset> #include <cctype> #include <cerrno> #include <clocale> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <exception> #include <fstream> #include <functional> #include <limits> #include <list> #include <map> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stdexcept> #include <streambuf> #include <string> #include <utility> #include <vector> #include <cwchar> #include <cwctype> #include <stack> #include <limits.h> using namespace std; #define MAXN 1010 int n,m,i,timer,tot; int u[MAXN],v[MAXN],dfn[MAXN],low[MAXN],degree[MAXN],head[MAXN]; struct Edge { int to,nxt; } e[MAXN]; inline void add(int u,int v) { tot++; e[tot] = (Edge){v,head[u]}; head[u] = tot; } inline void tarjan(int u,int fa) { int i,v; dfn[u] = low[u] = ++timer; for (i = head[u]; i; i = e[i].nxt) { v = e[i].to; if (v != fa) { if (!dfn[v]) { tarjan(v,u); low[u] = min(low[u],low[v]); } else low[u] = min(low[u],dfn[v]); } } } inline void calc() { int i,cnt = 0; for (i = 1; i <= m; i++) { if (low[u[i]] != low[v[i]]) { degree[low[u[i]]]++; degree[low[v[i]]]++; } } for (i = 1; i <= n; i++) cnt += (degree[i] == 1); printf("%d ",(cnt+1)/2); } int main() { scanf("%d%d",&n,&m); for (i = 1; i <= m; i++) { scanf("%d%d",&u[i],&v[i]); add(u[i],v[i]); add(v[i],u[i]); } tarjan(1,-1); calc(); return 0; }