题意:
给一个有n个结点的连通无向图,求它的割点个数。
思路:
裸求割点,直接上模板,这个模板是从一本书上找的,很简洁。
代码:
//poj 1144
#include <iostream>
using namespace std;
const int maxN=128;
int g[maxN][maxN];
int bridge[maxN][maxN];
int dfn[maxN],low[maxN],vis[maxN],cut[maxN];
int n;
void cut_bridge(int cur,int father,int dep)
{
vis[cur]=1;dfn[cur]=low[cur]=dep;
int children=0;
for(int i=1;i<=n;++i) if(g[cur][i]){
if(i!=father&&vis[i]==1)
low[cur]=min(low[cur],dfn[i]);
if(vis[i]==0){
cut_bridge(i,cur,dep+1);
++children;
low[cur]=min(low[cur],low[i]);
if((father==-1&&children>1)||(father!=-1&&low[i]>=dfn[cur]))
cut[cur]=1;
if(low[i]>dfn[cur]){bridge[i][cur]=bridge[cur][i]=1;}
}
}
}
int main()
{
while(scanf("%d",&n)==1&&n){
int x;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(vis,0,sizeof(vis));
memset(bridge,0,sizeof(bridge));
memset(cut,0,sizeof(cut));
memset(g,0,sizeof(g));
while(scanf("%d",&x)==1&&x){
while(getchar()!='\n'){
int y;
scanf("%d",&y);
g[x][y]=g[y][x]=1;
}
}
cut_bridge(1,-1,0);
int ans=0;
for(int i=1;i<=n;++i) if(cut[i]==1) ++ans;
printf("%d\n",ans);
}
return 0;
}