求割点
Code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 100 + 5;
int ind;
int root;
int low[maxn];
int dfs[maxn];
bool vis[maxn];
bool flag[maxn];
vector<int> mp[maxn];
void tarjan( int u )
{
int nsons = 0;
dfs[u] = low[u] = ++ind;
vis[u] = true;
for( int i = 0; i < mp[u].size(); i++ )
{
int x = mp[u][i];
if( !vis[x] )
{
nsons++;
tarjan( x );
low[u] = min( low[x], low[u] );
if( ( u == root && nsons == 2 ) || ( u != root && low[x] >= dfs[u] ) )
flag[u] = 1;
}
else if( u != x )
{
low[u] = min( low[u], dfs[x] );
}
}
}
void init()
{
memset( low, 0, sizeof( low ) );
memset( dfs, 0, sizeof( dfs ) );
memset( vis, 0, sizeof( vis ) );
memset( flag, 0, sizeof( flag ) );
}
int main()
{
int n;
while( scanf( "%d", &n ), n )
{
char ch;
int x, y;
int ans = 0;
init();
for( int i = 0; i <= maxn; i++ )
mp[i].clear();
while( scanf( "%d", &x ), x )
{
while( ( ch = getchar() ) != '\n' )
{
scanf( "%d", &y );
mp[x].push_back( y );
mp[y].push_back( x );
}
}
ind = 0;
root = 1;
tarjan( root );
for( int i = 1; i <= n; i++ )
if( flag[i] ) ans++;
printf( "%d\n", ans );
}
return 0;
}