给出n个点,还有点u连接的边,求解有多少割点
注意,对于根来说,只有子树大于一个才会是割点。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
#define maxn 120
struct node
{
int u , v ;
int next ;
} edge[1000000];
int head[maxn] , cnt , vis[1000000] ;
int dnf[maxn] , low[maxn] , time , ans , flag[maxn] , num ;
stack <int> sta;
void add(int u,int v)
{
edge[cnt].u = u ;
edge[cnt].v = v ;
edge[cnt].next = head[u] ;
head[u] = cnt++ ;
edge[cnt].u = v ;
edge[cnt].v = u ;
edge[cnt].next = head[v] ;
head[v] = cnt++ ;
}
void tarjan(int u)
{
dnf[u] = low[u] = ++time ;
int v , i , j ;
for( i = head[u] ; i != -1 ; i = edge[i].next )
{
if( vis[i] ) continue ;
if(u == 1)
num++ ;
vis[i] = vis[ i^1 ] = 1 ;
v = edge[i].v ;
if( !dnf[v] )
{
sta.push(i) ;
tarjan(v) ;
low[u] = min( low[u],low[v] );
if( low[v] >= dnf[u] && !flag[u])
{
ans++ ;
flag[u] = 1 ;
}
}
else if( dnf[v] < dnf[u] )
{
sta.push(v) ;
low[u] = min( low[u],dnf[v] );
}
}
}
int main()
{
int n , m , u , v ;
char ch ;
while(scanf("%d", &n) && n)
{
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(dnf,0,sizeof(dnf));
memset(low,0,sizeof(low));
memset(flag,0,sizeof(flag)) ;
cnt = time = ans = num = 0 ;
while(scanf("%d", &u) && u)
{
while(scanf("%d%c", &v, &ch) )
{
add(u,v);
if(ch == '\n')
break;
}
}
while( !sta.empty() )
sta.pop();
tarjan(1);
if(num == 1)
ans--;
printf("%d\n", ans);
}
return 0;
}
原文:http://blog.csdn.net/winddreams/article/details/38847013