【问题描述】
输入文件名: gd.in
7
1 2
2 3
2 4
3 4
4 5
4 6
4 7
5 6
6 7
输出文件名:gd.out
2
2
4
/* tarjan求割点 dfs一边,满足下面两种情况之一的节点就是割点 ①v是根节点,并且它有超过两个子节点。 ②v不是叶子节点,并且v的子节点w没有返祖边(即low[w]>=dfs[v]) */ #include<iostream> #include<cstdio> #define M 110 using namespace std; int num[M],low[M],s[M*2],instack[M],vis[M],top,indexx; int ok[M],head[M],tot,c1,n,m,cnt; struct node { int v,pre; };node e[M*M*2]; void add(int x,int y) { cnt++; e[cnt].v=y; e[cnt].pre=head[x]; head[x]=cnt; } void tarjan(int v) { num[v]=low[v]=++indexx; instack[v]=vis[v]=1; s[++top]=v; for(int i=head[v];i;i=e[i].pre) { int w=e[i].v; if(!vis[w]) { if(v==1)c1++; tarjan(w); low[v]=min(low[w],low[v]); if(v!=1&&low[w]>=num[v])ok[v]=1; } else if(instack[w]) low[v]=min(num[w],low[v]); } } int main() { freopen("gd.in","r",stdin); freopen("gd.out","w",stdout); scanf("%d",&n); int x,y; while(scanf("%d%d",&x,&y)!=EOF) { add(x,y);add(y,x); } tarjan(1); if(c1>=2)ok[1]=1; for(int i=1;i<=n;i++) if(ok[i]) { printf("%d\n",i); break; } return 0; }
原文:http://www.cnblogs.com/harden/p/5840246.html