Description
Input
Output
Sample Input
5 5 1 2 3 4 0 6 2 1 3 5 4 6 2 0 0
Sample Output
1 2
Hint
给出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; }