题意:给出一个$N$个点、$M$条边的无向图,找出其中的点,满足去掉该点与和它相连的边之后,这个图会变成一棵树。$N , M \leq 10^5$
说是毒瘤,真的不毒瘤
思考一下,我们需要找的就是度为$M - (N - 1 - 1)$且不是割点的点,直接tarjan即可
想起来在某luogu题解里把tarjan写成targan
#include<bits/stdc++.h> #define MAXN 100001 using namespace std; inline int read(){ ; char c = getchar(); while(!isdigit(c)) c = getchar(); while(isdigit(c)){ a = (a << ) + (a << ) + (c ^ '); c = getchar(); } return a; } struct Edge{ int end , upEd; }Ed[MAXN << ]; int head[MAXN] , dfn[MAXN] , low[MAXN] , in[MAXN] , ts , cntEd , N , M; bool vis[MAXN]; inline void addEd(int a , int b){ Ed[++cntEd].end = b; Ed[cntEd].upEd = head[a]; head[a] = cntEd; in[a]++; } void tarjan(int a , int fa){ dfn[a] = low[a] = ++ts; ; for(int i = head[a] ; i ; i = Ed[i].upEd) if(Ed[i].end != fa) if(!dfn[Ed[i].end]){ tarjan(Ed[i].end , a); low[a] = min(low[Ed[i].end] , low[a]); ch++; ) vis[a] = ; } else low[a] = min(low[a] , dfn[Ed[i].end]); && ch >= ) vis[a] = ; } int main(){ N = read(); M = read(); ; i <= M ; i++){ int a = read() , b = read(); addEd(a , b); addEd(b , a); } tarjan( , ); ; ; i <= N ; i++) && !vis[i]) ans++; cout << ans << endl; ; i <= N ; i++) && !vis[i]) cout << i << ' '; ; }