1. 程式人生 > >UOJ#67 新年的毒瘤 tarjan

UOJ#67 新年的毒瘤 tarjan

-s digi def git 傳送門 ont dig main max

題目傳送門

題意:給出一個$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 }

UOJ#67 新年的毒瘤 tarjan