uoj#67 新年的毒瘤【Tarjan】

题目http://uoj.ac/problem/67

题意:n个节点m条边的图,删除某个节点及他相连的所有边之后,剩下的图就成了一棵树。找出所有这样的节点。

思路:上次去清华面试的B题,当时就是在瞎写。太菜了。

其实就是两点,一是删除一个点是树,那么剩下来只有$n-2$条边。也就是说删掉的那个点的度是$m - (n - 2)$

其次,删掉了这个点之后还需要保证图的连通性,也就是说割点一定不是。

所以就先用Tarjan求出所有割点,再找不是割点且度是$m - (n - 2)$的点。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<map>
 4 #include<set>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<cmath> 
 9 #include<stack>
10 #include<queue>
11 #include<iostream>
12 
13 #define inf 0x3f3f3f3f
14 using namespace std;
15 typedef long long LL;
16 typedef pair<int, int> pr;
17 
18 int n, m;
19 const int maxn = 1e5 + 5;
20 struct edge{
21     int to, nxt;
22 }e[maxn * 2];
23 int tot = 1, head[maxn], dfn[maxn], low[maxn];
24 
25 void add(int x, int y)
26 {
27     e[++tot].to = y;
28     e[tot].nxt = head[x];
29     head[x] = tot;
30     e[++tot].to = x;
31     e[tot].nxt = head[y];
32     head[y] = tot;
33 }
34 
35 int num, root;
36 bool cut[maxn];
37 void tarjan(int x)
38 {
39     dfn[x] = low[x] = ++num;
40     int flag = 0;
41     for(int i = head[x]; i; i = e[i].nxt){
42         int y = e[i].to;
43         if(!dfn[y]){
44             tarjan(y);
45             low[x] = min(low[x], low[y]);
46             if(low[y] >= dfn[x]){
47                 flag++;
48                 if(x != root || flag > 1)cut[x] = true;
49             }
50         }
51         else low[x] = min(low[x], dfn[y]);
52     }
53 }
54 
55 int deg[maxn];
56 int main()
57 {
58     scanf("%d%d", &n, &m);
59     for(int i = 0; i < m; i++){
60         int x, y;
61         scanf("%d%d", &x, &y);
62         add(x, y);
63         deg[x]++;deg[y]++;
64     }
65     for(int i = 1; i <= n; i++){
66         if(!dfn[i]){
67             root = i;
68             tarjan(i);
69         }
70     }
71     vector<int>ans;
72     for(int i = 1; i <= n; i++){
73         if(!cut[i] && deg[i] == m - (n - 2))ans.push_back(i);
74     }
75     printf("%d
%d", ans.size(), ans[0]);
76     for(int i = 1; i < ans.size(); i++){
77         printf(" %d", ans[i]);
78     }
79     printf("
");
80     return 0;
81 }

---恢复内容结束---

原文地址:https://www.cnblogs.com/wyboooo/p/11120554.html