pku 1144 Network(tarjan算法求割点个数)
求无向图的割点个数。注意根结点是不是有多个儿子!!
#include <stdio.h>
#include <string.h>
#define MAXN 101
#define MAXM 10000
struct edge
{
int adv,next;
};
edge p[MAXM];
int index;
int adjlist[MAXN];
int N,root=1,times,dfn[MAXN],low[MAXN];
bool cut[MAXN];
inline void insert(int i,int j)
{
p[index].adv=j;
p[index].next=adjlist[i];
adjlist[i]=index++;
}
void print()
{
int i,j;
for(i=1;i<=N;i++)
{
printf("%d : ",i);
for(j=adjlist[i]; j != -1; j=p[j].next)
{
printf("%d ",p[j].adv);
}
printf("\n");
}
}
inline int Min(int a,int b)
{
return a<b?a:b;
}
void dfs(int u,int ufa)
{
int rootson=0;
dfn[u]=low[u]=++times;
for(int j=adjlist[u]; j != -1; j=p[j].next)
{
int v=p[j].adv;
if( !dfn[v] )
{
if(u==root)
{
if(++rootson>1) cut[u]=true;//根有多个儿子,则是割点
}
dfs(v,u);
low[u]=Min(low[u],low[v]);
if( u != root && dfn[u] <= low[v]) cut[u]=true;//注意u!=root
}
else if(v!=ufa)
{
low[u]=Min(low[u],dfn[v]);
}
}
}
int main()
{
int i,j;
char ch;
while(scanf("%d",&N),N)
{
index=0;
memset(adjlist,-1,sizeof(adjlist));
while(scanf("%d",&i),i)
{
while( (ch=getchar()) != '\n' )
{
scanf("%d",&j);
insert(i,j);
insert(j,i);
}
}
// print();
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(cut,false,sizeof(cut));
times=0;
dfs(root,-1);
int cutnum=0;
for(i=1;i<=N;i++)
if(cut[i]) cutnum++;
printf("%d\n",cutnum);
}
return 0;
}