1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| struct Edge { int id, v; }; vector<Edge> adj[maxn]; vector<int> comp[maxn]; vector<Edge> tree[maxn];
int dfn[maxn], low[maxn], timer; bool bridge[maxm]; int bcnt;
int ebcc[maxn], ecnt;
void add_edge( int u, int v, int id ) { adj[u].push_back({ id, v }); adj[v].push_back({ id, u }); }
void tarjan( int u, int in_edge ) { dfn[u] = low[u] = ++ timer; for( auto [id, v] : adj[u] ) { if( !dfn[v] ) { tarjan( v, id ); low[u] = min( low[u], low[v] ); if( low[v] > dfn[u] ) { bridge[id] = true; ++ bcnt; } } else if( id != in_edge ) { low[u] = min( low[u], dfn[v] ); } } }
int deg[maxn];
void dfs_ebcc( int u, int id ) { ebcc[u] = id; for( auto [eid, v] : adj[u] ) { if( bridge[eid] || ebcc[v] ) continue; dfs_ebcc( v, id ); } }
void solve( ) { int n = read( ), m = read( ); for( int i = 1; i <= m; ++ i ) { int u = read( ), v = read( ); add_edge( u, v, i ); } for( int i = 1; i <= n; ++ i ) { if( !dfn[i] ) tarjan( i, 0 ); } for( int i = 1; i <= n; ++ i ) { if( !ebcc[i] ) dfs_ebcc( i, ++ ecnt ); }
for( int u = 1; u <= n; ++ u ) { for( auto [id, v] : adj[u] ) { if( bridge[id] ) deg[ebcc[v]] ++; } }
int cnt = 0; for( int i = 1; i <= ecnt; ++ i ) { if( deg[i] == 1 ) ++ cnt; } cout << ( cnt + 1 ) / 2 << '\n'; }
|