#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
struct arc
{
int to,val;
int next;
arc(int a=-1,int b=0):to(a),val(b) {}
};
int head[150];
arc edge[40000];
int e_cnt=0;
int low[150];
int dfn[150];
int cnt;
int rootnum; //深度优先树根的边树
int root; //深度优先树根节点
int n;
bool ans[150]; //记录割点
inline void addedge(int a,int b)
{
edge[e_cnt].to=b;
edge[e_cnt].next=head[a];
head[a]=e_cnt;
e_cnt++;
}
void dfs(int from,int x)
{
low[x]=dfn[x]=++cnt;
int v;
for(int i=head[x];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(!dfn[v])
{
if(x==root) rootnum++;
dfs(x,v);
low[x]=min(low[v],low[x]);
if(low[v]>=dfn[x]) ans[x]=1;
//存在一个子节点的最小可达深度优先数小于父节点的深度优先数 则为割点
}
else if(v!=from) low[x]=min(dfn[v],low[x]);
}
return;
}
void tarjan()
{
rootnum=cnt=0;
memset(dfn,0,sizeof(dfn));
memset(ans,0,sizeof(ans));
dfs(-1,root);
return;
}
int main()
{
char str[500];
while(~scanf("%d",&n)&&n)
{
getchar();
e_cnt=0;
memset(head,-1,sizeof(head));
while(gets(str)&&str[0]!='0')
{
int len=strlen(str);
int k;
int from;
root=from=atoi(str);
for(k=0;str[k]!=' ';k++) {continue;}
while(k<len)
{
if(str[k]==' ') {k++; continue;}
int to=atoi(str+k);
addedge(from,to);
addedge(to,from);
for(;str[k]!=' '&&str[k];k++) continue;
}
}
tarjan(); //从from开始进行tarjan算法的dfs
// for(int i=1;i<=n;i++)
// {
// cout<<i<<':'<<' ';
// for(int j=head[i];j!=-1;j=edge[j].next)
// {
// cout<<edge[j].to<<" ";
// }
// cout<<endl;
// }
int res=0;
for(int i=1;i<=n;i++)
if(ans[i]&&i!=root) res++;
if(rootnum>=2) res++; //根节点如果边树大于2 则为割点
// for(int i=1;i<=n;i++)
// {
// printf("%d: low=%d dfn=%d\n",i,low[i],dfn[i]);
// }
printf("%d\n",res);
}
return 0;
}
hrbust 1494 tarjan算法求割点模版
最新推荐文章于 2019-02-20 21:19:07 发布