题目链接:https://vjudge.net/problem/UVA-315#author=0
题意:给出一个无向图,求割顶。
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstring>
#include <iostream>
#include <cmath>
#include <map>
#include <list>
#include <stack>
using namespace std;
const int maxn=105;
vector <int> g[maxn];
int pre[maxn],iscut[maxn],clock1,low[maxn];//pre 第一次访问时间戳 low 当前点所能到达的最早的祖先拥有的时间戳
int dfs(int u,int fa)//把一个可能存在环的图按照树来遍历
{
int lowu=pre[u]=++clock1;
int ch=0;
for(int i=0; i<g[u].size(); i++)
{
int v=g[u][i];
if(!pre[v])
{
ch++;
int lowv=dfs(v,u);
lowu=min(lowu,lowv);
if(lowv>=pre[u])//结合下面特判 考虑环和1-2/2-3/3-1/1-4的情况
iscut[u]=1;
}
else if(pre[v]<pre[u]&&v!=fa)
{
lowu=min(lowu,pre[v]);
}
}
if(fa<0&&ch==1)//对起始点进行特判 真正的儿子数<=1就不是割顶
iscut[u]=0;
low[u]=lowu;
return lowu;
}
int main()
{
int n;
while(scanf("%d",&n))
{
if(!n)
break;
clock1=0;
for(int i=0; i<=n; i++)
{
g[i].clear();
pre[i]=low[i]=iscut[i]=0;
}
int m;
for(int i=0; 1; i++)
{
scanf("%d",&m);
if(!m)
break;
char ch;
int x;
while((ch=getchar())!='\n')
{
scanf("%d",&x);
g[m].push_back(x);
g[x].push_back(m);
}
}
for(int i=1; i<=n; i++)
{
if(!pre[i])
dfs(i,-1);
}
int cnt=0;
for(int i=1; i<=n; i++)
{
if(iscut[i])
cnt++;
}
printf("%d\n",cnt);
}
return 0;
}