无向图判断割点
题目链接:https://vjudge.net/contest/67418#problem/B
具体思路:对根节点,也就是起点,单独判断左右子树的个数,如果大于等于二的话,那么就是割点。对于与其他点,就判断它最早能达到的点,如果能达到的点大于它的时间割,那么它就是割点。
AC代码:
1 #include<iostream>
2 #include<string>
3 #include<cstring>
4 #include<iomanip>
5 #include<cmath>
6 #include<stdio.h>
7 #include<algorithm>
8 #include<vector>
9 #include<queue>
10 #include<stack>
11 #include<map>
12 #include<set>
13 using namespace std;
14 # define inf 0x3f3f3f3f
15 # define maxn 151
16 # define ll long long
17 vector<int>wakaka[maxn];
18 int n,num,root,root_son;
19 int dfn[maxn];
20 int low[maxn];
21 int cur[maxn];
22 void init()
23 {
24 num=0;
25 root=1;
26 root_son=0;
27 memset(dfn,0,sizeof(dfn));
28 memset(low,0,sizeof(low));
29 memset(cur,0,sizeof(cur));
30 for(int i=1; i<=n; i++)
31 {
32 wakaka[i].clear();
33 }
34 }
35 void addage(int u,int v)
36 {
37 wakaka[u].push_back(v);
38 }
39 void tarjan(int u)
40 {
41 dfn[u]=low[u]=++num;
42 int len=wakaka[u].size();
43 for(int i=0; i<len; i++)
44 {
45 int v=wakaka[u][i];
46 if(!dfn[v])
47 {
48 tarjan(v);
49 if(u==root)
50 {
51 root_son++;
52 }
53 else
54 {
55 low[u]=min(low[u],low[v]);
56 if(low[v]>=dfn[u])
57 {
58 cur[u]=1;
59 }
60 }
61 }
62 else if(dfn[v])low[u]=min(low[u],dfn[v]);
63 }
64 }
65 int main()
66 {
67 while(~scanf("%d",&n)&&n)
68 {
69 init();
70 int temp;
71 char str;
72 int u,v;
73 while(~scanf("%d",&u)&&u)
74 {
75 while(getchar()!='\n')
76 {
77 scanf("%d",&v);
78 addage(u,v);
79 addage(v,u);
80 }
81 }
82 tarjan(root);
83 int ans=0;
84 if(root_son>1)cur[root]=1;
85 for(int i=1; i<=n; i++)
86 {
87 if(cur[i])ans++;
88 }
89 printf("%d\n",ans);
90 }
91 return 0;
92 }
93