题意:给出一个$N$个点、$M$条边的无向图,找出其中的点,满足去掉该点与和它相连的边之后,这个图会变成一棵树。$N , M \leq 10^5$
说是毒瘤,真的不毒瘤
思考一下,我们需要找的就是度为$M - (N - 1 - 1)$且不是割点的点,直接tarjan即可
想起来在某luogu题解里把tarjan写成targan
1 #include<bits/stdc++.h> 2 #define MAXN 100001 3 using namespace std; 4 5 inline int read(){ 6 int a = 0; 7 char c = getchar(); 8 while(!isdigit(c)) 9 c = getchar(); 10 while(isdigit(c)){ 11 a = (a << 3) + (a << 1) + (c ^ ‘0‘); 12 c = getchar(); 13 } 14 return a; 15 } 16 17 struct Edge{ 18 int end , upEd; 19 }Ed[MAXN << 1]; 20 21 int head[MAXN] , dfn[MAXN] , low[MAXN] , in[MAXN] , ts , cntEd , N , M; 22 bool vis[MAXN]; 23 24 inline void addEd(int a , int b){ 25 Ed[++cntEd].end = b; 26 Ed[cntEd].upEd = head[a]; 27 head[a] = cntEd; 28 in[a]++; 29 } 30 31 void tarjan(int a , int fa){ 32 dfn[a] = low[a] = ++ts; 33 int ch = 0; 34 for(int i = head[a] ; i ; i = Ed[i].upEd) 35 if(Ed[i].end != fa) 36 if(!dfn[Ed[i].end]){ 37 tarjan(Ed[i].end , a); 38 low[a] = min(low[Ed[i].end] , low[a]); 39 ch++; 40 if(low[Ed[i].end] >= dfn[a] && a != 1) 41 vis[a] = 1; 42 } 43 else 44 low[a] = min(low[a] , dfn[Ed[i].end]); 45 if(a == 1 && ch >= 2) 46 vis[a] = 1; 47 } 48 49 int main(){ 50 N = read(); 51 M = read(); 52 for(int i = 1 ; i <= M ; i++){ 53 int a = read() , b = read(); 54 addEd(a , b); 55 addEd(b , a); 56 } 57 tarjan(1 , 0); 58 int ans = 0; 59 for(int i = 1 ; i <= N ; i++) 60 if(in[i] == M - N + 2 && !vis[i]) 61 ans++; 62 cout << ans << endl; 63 for(int i = 1 ; i <= N ; i++) 64 if(in[i] == M - N + 2 && !vis[i]) 65 cout << i << ‘ ‘; 66 return 0; 67 }
原文地址:https://www.cnblogs.com/Itst/p/9783948.html
时间: 2024-10-28 15:46:15