UOJ#67 新年的毒瘤 tarjan
阿新 • • 發佈:2018-10-13
-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