图论,割点求法

 

 

/******************************************************************** ** @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 #include #include #include using namespace std; #define MAX 111 int low[MAX],dfn[MAX]; bool vis[MAX], flag[MAX]; vectorg[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=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<

你可能感兴趣的:(ACM)