Status DFSArticul(MGraph graph, int vex_index, int *count, int articulated[MAXVEX + 1], int visited_sequ[MAXVEX], int vex_can_arrived[MAXVEX]) {
	int nextvex;

	visited_sequ[vex_index] = *count;
	++*count;
	vex_can_arrived[vex_index] = visited_sequ[vex_index];	//min(自己的序号,儿子能到达的最早序号,自己的祖先边中祖先的序号)

	for (nextvex = FirstAdjVex(graph, vex_index); nextvex != -1; nextvex = NextAdjVex(graph, vex_index, nextvex)) {
		if (visited_sequ[nextvex] == -1) {
			DFSArticul(graph, nextvex, count, articulated, visited_sequ, vex_can_arrived);
			if (vex_can_arrived[nextvex] < vex_can_arrived[vex_index]) {
				vex_can_arrived[vex_index] = vex_can_arrived[nextvex];
			}
			if (vex_can_arrived[nextvex] >= visited_sequ[vex_index]) {
				int i;
				for (i = 1; i <= articulated[0]; ++i)	//如果该点已经添加过了,则不必再添加
					if (articulated[i] == graph.vexs[vex_index])
						break;
				if (i == articulated[0] + 1) {
					++articulated[0];
					articulated[articulated[0]] = graph.vexs[vex_index];
				}
			}
		}
		else if (visited_sequ[nextvex] < vex_can_arrived[vex_index]) {
			vex_can_arrived[vex_index] = visited_sequ[nextvex];
		}
	}
	return OK;
}
 void FindArticul(ALGraph G)
 { /* 连通图G以邻接表作存储结构,查找并输出G上全部关节点。算法7.10 */
   /* 全局量count对访问计数。 */
   int i,v;
   ArcNode *p;
   count=1;
   low[0]=visited[0]=1; /* 设定邻接表上0号顶点为生成树的根 */
   for(i=1;i<G.vexnum;++i)
     visited[i]=0; /* 其余顶点尚未访问 */
   p=G.vertices[0].firstarc;
   v=p->adjvex;
   DFSArticul(G,v); /* 从第v顶点出发深度优先查找关节点 */
   if(count<G.vexnum) /* 生成树的根有至少两棵子树 */
   {
     printf("%d %s\n",0,G.vertices[0].data); /* 根是关节点,输出 */
     while(p->nextarc)
     {
       p=p->nextarc;
       v=p->adjvex;
       if(visited[v]==0)
         DFSArticul(G,v);
     }
   }
 }
Beispiel #3
0
void  DFSArticul(ALGraph G, int v0 ) {  // 算法7.11
  // 从第v0个顶点出发深度优先遍历图G,查找并输出关节点
  int min,w;
  struct ArcNode *p;
  visited[v0] = min = ++count;  // v0是第count个访问的顶点
  for (p=G.vertices[v0].firstarc; p!=NULL; p=p->nextarc) { 
    // 检查v0的每个邻接顶点
    w = p->adjvex;              // w为v0的邻接顶点
    if (visited[w] == 0) {      // w未曾被访问,是v0的孩子
      DFSArticul(G, w);         // 返回前求得low[w]
      if (low[w] < min)  min = low[w];
      if (low[w] >= visited[v0]) 
        printf(v0, G.vertices[v0].data);  // 输出关节点
    } 
    else if (visited[w] < min)  min = visited[w];  
        // w已被访问,w是v0在生成树上的祖先   
  }//for
  low[v0] = min;
} // DFSArticul
 void DFSArticul(ALGraph G,int v0)
 { /* 从第v0个顶点出发深度优先遍历图G,查找并输出关节点。算法7.11 */
   int min,w;
   ArcNode *p;
   visited[v0]=min=++count; /* v0是第count个访问的顶点 */
   for(p=G.vertices[v0].firstarc;p;p=p->nextarc) /* 对v0的每个邻接顶点检查 */
   {
     w=p->adjvex; /* w为v0的邻接顶点 */
     if(visited[w]==0) /* w未曾访问,是v0的孩子 */
     {
       DFSArticul(G,w); /* 返回前求得low[w] */
       if(low[w]<min)
         min=low[w];
       if(low[w]>=visited[v0])
         printf("%d %s\n",v0,G.vertices[v0].data); /* 关节点 */
     }
     else if(visited[w]<min)
       min=visited[w]; /* w已访问,w是v0在生成树上的祖先 */
   }
   low[v0]=min;
 }
Status FindArticul(MGraph graph, int articulated[MAXVEX + 1]) {
	int visited_sequ[MAXVEX];		//被访问的序列号
	int vex_can_arrived[MAXVEX];	//能到达的最早被访问的序列号
	int index, i;
	int count;

	if (graph.vexnum < 2)
		return ERROR;
	if (!articulated)
		return ERROR;

	articulated[0] = 0;
	count = 0;
	for (i = 0; i < graph.vexnum; ++i)		//访问序列初始化
		visited_sequ[i] = -1;

	for (i = 0; i < graph.vexnum; ++i) {
		if (visited_sequ[i] == -1) {
			visited_sequ[i] = count;
			++count;

			if ((index = FirstAdjVex(graph, i)) == -1)	//不能存在度为0的点(独立构成一个连通分量)
				return ERROR;

			// 对根的一棵子树进行遍历,找出关节点
			DFSArticul(graph, index, &count, articulated, visited_sequ, vex_can_arrived);

			// 判断根是否是关节点
			for (index = FirstAdjVex(graph, i); index != -1; index = NextAdjVex(graph, i, index)) {
				if (visited_sequ[index] == -1) {
					++articulated[0];
					articulated[articulated[0]] = graph.vexs[i];
					break;
				}
			}
		}
	}
	return OK;
}