题意:
一个无向连通图,若去掉某个点后这个图变成了非连通图,这个点成为关键点,求关键点的数目。
题解:
1.关键点就是割点,套用Tarjan模板:https://www.cnblogs.com/collectionne/p/6847240.html
#include <bits/stdc++.h>
#define N 105
#define inf 0x3f3f3f3f
#define mod 1000000007
using namespace std;
int n ;
bool vis[N] ;
int low[N] ;
int dfn[N] ;
int parent[N] ;
bool cut_point[N] ;
vector <int> edge[N] ;
void Tarjin(int u , int m)
{
int i , j ;
int v ;
int children = 0 ;
vis[u] = 1 ;
dfn[u] = m ;
low[u] = m ;
for(i = 0 ; i < edge[u].size() ; i ++)
{
v = edge[u][i] ;
if(!vis[v])
{
children ++ ;
parent[v] = u ;
Tarjin(v , m + 1) ;
low[u] = min(low[u] , low[v]) ;
if(parent[u] == -1 && children >= 2) //u是根节点且子树数目大于等于2
cut_point[u] = 1 ;
if(parent[u] != -1 && low[v] >= dfn[u]) //u不是根节点且子节点的low不小于自己的dfn
cut_point[u] = 1 ;
}
else if(parent[u] != v)
low[u] = min(low[u] , dfn[v]) ;
}
}
int main()
{
int i , j ;
int u , v ;
int ans = 0 ;
char c ;
while(scanf("%d" , &n) && n != 0)
{
for(i = 1 ; i <= n ; i ++)
edge[i].clear() ;
while(scanf("%d" , &u) && u != 0)
{
while(1)
{
scanf("%d%c" , &v , &c) ;
edge[u].push_back(v) ;
edge[v].push_back(u) ;
if(c == '\n')
break ;
}
}
memset(low , inf , sizeof(low)) ;
memset(dfn , inf , sizeof(dfn)) ;
memset(parent , -1 , sizeof(parent)) ;
memset(vis , 0 , sizeof(vis)) ;
memset(cut_point , 0 , sizeof(cut_point)) ;
Tarjin(1 , 1) ;
ans = 0 ;
for(i = 1 ; i <= n ; i ++)
if(cut_point[i])
ans ++ ;
printf("%d\n" , ans) ;
}
}