1
/*
2 找无向连通的割点
3 */
4
5 // include file
6 #include < cstdio >
7 #include < cstdlib >
8 #include < cstring >
9 #include < cmath >
10 #include < cctype >
11 #include < ctime >
12
13 #include < iostream >
14 #include < sstream >
15 #include < fstream >
16 #include < iomanip >
17 #include < bitset >
18
19 #include < algorithm >
20 #include < string >
21 #include < vector >
22 #include < queue >
23 #include < set >
24 #include < list >
25 #include < functional >
26
27 using namespace std;
28
29 // typedef
30 typedef long long LL;
31 typedef unsigned long long ULL;
32 typedef __int64 Bint;
33
34 //
35 #define read freopen("in.txt","r",stdin)
36 #define write freopen("out.txt","w",stdout)
37 #define FORi(a,b,c) for(int i=(a);i<(b);i+=c)
38 #define FORj(a,b,c) for(int j=(a);j<(b);j+=c)
39 #define FORk(a,b,c) for(int k=(a);k<(b);k+=c)
40 #define FORp(a,b,c) for(int p=(a);p<(b);p+=c)
41 #define FORii(a,b,c) for(int ii=(a);ii<(b);ii+=c)
42 #define FORjj(a,b,c) for(int jj=(a);jj<(b);jj+=c)
43 #define FORkk(a,b,c) for(int kk=(a);kk<(b);kk+=c)
44
45 #define FF(i,a) for(int i=0;i<(a);i++)
46 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
47
48 #define Z(a) (a<<1)
49 #define Y(a) (a>>1)
50
51 const double eps = 1e - 6 ;
52 const double INFf = 1e10;
53 const int INFi = 1000000000 ;
54 const double Pi = acos( - 1.0 );
55
56 template < class T > inline T sqr(T a){ return a * a;}
57 template < class T > inline T TMAX(T x,T y)
58 {
59 if (x > y) return x;
60 return y;
61 }
62 template < class T > inline T TMIN(T x,T y)
63 {
64 if (x < y) return x;
65 return y;
66 }
67 template < class T > inline void SWAP(T & x,T & y)
68 {
69 T t = x;
70 x = y;
71 y = t;
72 }
73 template < class T > inline T MMAX(T x,T y,T z)
74 {
75 return TMAX(TMAX(x,y),z);
76 }
77
78
79 // code begin
80 #define MAXN 110
81
82 int N;
83 struct node1
84 {
85 int e;
86 int next;
87 };
88 struct node2
89 {
90 int next;
91 };
92 node1 mem[MAXN * MAXN];
93 node2 G[MAXN];
94 int dfn[MAXN];
95 int low[MAXN];
96 int cut[MAXN];
97 int used[MAXN];
98 int cnt;
99
100 void Add_edge( int dx, int a, int b)
101 {
102 mem[dx].e = b;
103 mem[dx].next = G[a].next;
104 G[a].next = dx;
105 }
106
107 void BCC_tarjan( int i, int fa)
108 {
109 dfn[i] = cnt;
110 low[i] = cnt;
111 cnt ++ ;
112 used[i] = true ;
113 int son = 0 ;
114 int dx = G[i].next;
115 while (dx !=- 1 )
116 {
117 int v = mem[dx].e;
118 if ( ! used[v])
119 {
120 BCC_tarjan(v,i);
121 low[i] = TMIN(low[i],low[v]);
122 if (fa ==- 1 ) son ++ ;
123 else if (low[v] >= dfn[i])
124 {
125 cut[i] = true ;
126 }
127 }
128 else if (v != fa)
129 {
130 low[i] = TMIN(low[i],dfn[v]);
131 }
132
133 dx = mem[dx].next;
134 }
135 if (fa ==- 1 && son > 1 ) cut[i] = true ;
136 }
137
138 void check()
139 {
140 printf( " N:%d\n " ,N);
141 FORi( 1 ,N + 1 , 1 )
142 {
143 printf( " %d: " ,i);
144 int dx = G[i].next;
145 while (dx !=- 1 )
146 {
147 printf( " %d " ,mem[dx].e);
148 dx = mem[dx].next;
149 }
150 printf( " \n " );
151 }
152 }
153
154 int main()
155 {
156 read;
157 write;
158 int a,b,dx;
159 while (scanf( " %d " , & N) !=- 1 )
160 {
161 if (N == 0 ) break ;
162 // getchar();
163 FORi( 1 ,N + 1 , 1 )
164 {
165 G[i].next = - 1 ;
166 }
167 dx = 0 ;
168 while (scanf( " %d " , & a) !=- 1 )
169 {
170 if (a == 0 )
171 {
172 break ;
173 }
174 while (getchar() != ' \n ' )
175 {
176 scanf( " %d " , & b);
177 Add_edge(dx ++ ,a,b);
178 Add_edge(dx ++ ,b,a);
179 }
180 }
181
182
183 // check();
184
185 memset(used, 0 , sizeof (used));
186 memset(dfn, 0 , sizeof (dfn));
187 memset(low, 0 , sizeof (low));
188 memset(cut, 0 , sizeof (cut));
189 cnt = 1 ;
190 FORi( 1 ,N + 1 , 1 )
191 {
192 if ( ! used[i])
193 {
194 BCC_tarjan(i, - 1 );
195 }
196 }
197
198 // 把所有的割点都标记好了
199 int ans = 0 ;
200 FORi( 1 ,N + 1 , 1 )
201 {
202 if (cut[i])
203 ans ++ ;
204 }
205 printf( " %d\n " ,ans);
206 }
207 return 0 ;
208 }
2 找无向连通的割点
3 */
4
5 // include file
6 #include < cstdio >
7 #include < cstdlib >
8 #include < cstring >
9 #include < cmath >
10 #include < cctype >
11 #include < ctime >
12
13 #include < iostream >
14 #include < sstream >
15 #include < fstream >
16 #include < iomanip >
17 #include < bitset >
18
19 #include < algorithm >
20 #include < string >
21 #include < vector >
22 #include < queue >
23 #include < set >
24 #include < list >
25 #include < functional >
26
27 using namespace std;
28
29 // typedef
30 typedef long long LL;
31 typedef unsigned long long ULL;
32 typedef __int64 Bint;
33
34 //
35 #define read freopen("in.txt","r",stdin)
36 #define write freopen("out.txt","w",stdout)
37 #define FORi(a,b,c) for(int i=(a);i<(b);i+=c)
38 #define FORj(a,b,c) for(int j=(a);j<(b);j+=c)
39 #define FORk(a,b,c) for(int k=(a);k<(b);k+=c)
40 #define FORp(a,b,c) for(int p=(a);p<(b);p+=c)
41 #define FORii(a,b,c) for(int ii=(a);ii<(b);ii+=c)
42 #define FORjj(a,b,c) for(int jj=(a);jj<(b);jj+=c)
43 #define FORkk(a,b,c) for(int kk=(a);kk<(b);kk+=c)
44
45 #define FF(i,a) for(int i=0;i<(a);i++)
46 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
47
48 #define Z(a) (a<<1)
49 #define Y(a) (a>>1)
50
51 const double eps = 1e - 6 ;
52 const double INFf = 1e10;
53 const int INFi = 1000000000 ;
54 const double Pi = acos( - 1.0 );
55
56 template < class T > inline T sqr(T a){ return a * a;}
57 template < class T > inline T TMAX(T x,T y)
58 {
59 if (x > y) return x;
60 return y;
61 }
62 template < class T > inline T TMIN(T x,T y)
63 {
64 if (x < y) return x;
65 return y;
66 }
67 template < class T > inline void SWAP(T & x,T & y)
68 {
69 T t = x;
70 x = y;
71 y = t;
72 }
73 template < class T > inline T MMAX(T x,T y,T z)
74 {
75 return TMAX(TMAX(x,y),z);
76 }
77
78
79 // code begin
80 #define MAXN 110
81
82 int N;
83 struct node1
84 {
85 int e;
86 int next;
87 };
88 struct node2
89 {
90 int next;
91 };
92 node1 mem[MAXN * MAXN];
93 node2 G[MAXN];
94 int dfn[MAXN];
95 int low[MAXN];
96 int cut[MAXN];
97 int used[MAXN];
98 int cnt;
99
100 void Add_edge( int dx, int a, int b)
101 {
102 mem[dx].e = b;
103 mem[dx].next = G[a].next;
104 G[a].next = dx;
105 }
106
107 void BCC_tarjan( int i, int fa)
108 {
109 dfn[i] = cnt;
110 low[i] = cnt;
111 cnt ++ ;
112 used[i] = true ;
113 int son = 0 ;
114 int dx = G[i].next;
115 while (dx !=- 1 )
116 {
117 int v = mem[dx].e;
118 if ( ! used[v])
119 {
120 BCC_tarjan(v,i);
121 low[i] = TMIN(low[i],low[v]);
122 if (fa ==- 1 ) son ++ ;
123 else if (low[v] >= dfn[i])
124 {
125 cut[i] = true ;
126 }
127 }
128 else if (v != fa)
129 {
130 low[i] = TMIN(low[i],dfn[v]);
131 }
132
133 dx = mem[dx].next;
134 }
135 if (fa ==- 1 && son > 1 ) cut[i] = true ;
136 }
137
138 void check()
139 {
140 printf( " N:%d\n " ,N);
141 FORi( 1 ,N + 1 , 1 )
142 {
143 printf( " %d: " ,i);
144 int dx = G[i].next;
145 while (dx !=- 1 )
146 {
147 printf( " %d " ,mem[dx].e);
148 dx = mem[dx].next;
149 }
150 printf( " \n " );
151 }
152 }
153
154 int main()
155 {
156 read;
157 write;
158 int a,b,dx;
159 while (scanf( " %d " , & N) !=- 1 )
160 {
161 if (N == 0 ) break ;
162 // getchar();
163 FORi( 1 ,N + 1 , 1 )
164 {
165 G[i].next = - 1 ;
166 }
167 dx = 0 ;
168 while (scanf( " %d " , & a) !=- 1 )
169 {
170 if (a == 0 )
171 {
172 break ;
173 }
174 while (getchar() != ' \n ' )
175 {
176 scanf( " %d " , & b);
177 Add_edge(dx ++ ,a,b);
178 Add_edge(dx ++ ,b,a);
179 }
180 }
181
182
183 // check();
184
185 memset(used, 0 , sizeof (used));
186 memset(dfn, 0 , sizeof (dfn));
187 memset(low, 0 , sizeof (low));
188 memset(cut, 0 , sizeof (cut));
189 cnt = 1 ;
190 FORi( 1 ,N + 1 , 1 )
191 {
192 if ( ! used[i])
193 {
194 BCC_tarjan(i, - 1 );
195 }
196 }
197
198 // 把所有的割点都标记好了
199 int ans = 0 ;
200 FORi( 1 ,N + 1 , 1 )
201 {
202 if (cut[i])
203 ans ++ ;
204 }
205 printf( " %d\n " ,ans);
206 }
207 return 0 ;
208 }