程序博客网 > linux打包zip命令
来源:互联网 发布:linux打包zip命令 编辑:程序博客网 时间:2024/05/11 04:00
/******************************************************************** ** @file poj1144.cpp ** @author liuke ** @date Sat Apr 30 00:28:42 2011 ** @brief 关节点也被称为是割点,在去掉这个点之后图将不再连通。 求割点的办法来源于两个事实: 1、若深度优先生成树的根有两棵或两棵以上的子树,则此根顶点必定为关节点。 2、若生成树中某个非叶子顶点v,其孩子结点均没有指向 v 的祖先的回边,则 v 为关节点。LOW(U) 的计算步骤:= dfn(U): 当 U 在 dfs 过程中被首次访问到时;= min(LOW(U), dfn(W)): 检查后向边 (U, W) 时;= min(LOW(U), LOW(S)): U 的儿子 S 的关联边全部被检查时。 **@version Copyright (c) 2011,河南理工大学-信管08-三班. ********************************************************************/#include<iostream>#include<cstdio>#include<vector>#include<cstring>using namespace std;#define MAX 111 int low[MAX],dfn[MAX];bool vis[MAX], flag[MAX];vector<int>g[MAX];int root,times,n;void init(){ times=1;root=1; memset(vis,false,sizeof(vis)); memset(flag,false,sizeof(flag));/*标记哪个顶点是关键点*/ memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); for(int i=0;i<=n;++i) g[i].clear(); int a,b;char ch; while(scanf("%d",&a)&&a){ while((ch=getchar())!='/n'){ scanf("%d",&b); g[a].push_back(b); g[b].push_back(a); } }}void dfs(int v){ int i,cnt=0,w;vis[v]=true; low[v]=dfn[v]=times++; for(i=0;i<g[v].size();++i){ w=g[v][i]; if(!vis[w]){ cnt++;dfs(w);low[v]=min(low[v],low[w]);/* 1、若深度优先生成树的根有两棵或两棵以上的子树,则此根顶点必定为关节点。*/ if(v==root && cnt==2)flag[v]=true;/**//* 2、若生成树中某个非叶子顶点v,其孩子结点均没有指向 v 的祖先的回边,则 v 为关节点。*/ if(v!=root && low[w]>=dfn[v])flag[v]=true; } else if(v!=w){/*有后向边情况*/ low[v]=min(low[v],dfn[w]); } }}int main(int argc, char *argv[]){ while(cin>>n&&n){ init(); int ans=0; dfs(root); for(int i=1;i<=n;++i) if(flag[i])ans++; cout<<ans<<endl; } return 0;}