数据结构_图_求无向图的关节点
head.h
#include<iostream>
using namespace std;
#define MAX_VEX_NUM 20
class ChildNode //存储以某顶点为边的一个顶点的另一个顶点
{
public:
ChildNode();
int child;
ChildNode *next;
};
ChildNode::ChildNode()
{
child = 0;
next = NULL;
}
class VexNode //顶点信息
{
public:
VexNode();
char name;
int visitsq; //访问顺序
int low; //low值
ChildNode *firstchild;
};
VexNode::VexNode()
{
visitsq = low = 0;
firstchild = NULL;
}
class VexBox //顶点集合
{
public:
VexBox();
int vexnum;
VexNode vexbox[MAX_VEX_NUM];
};
VexBox::VexBox()
{
vexnum = 0;
}
class ArtPoint //Articulation Point//关节点类
{
public:
void GetArtPoint(); //接口函数
private:
void GetVexNode(); //得到顶点信息
void GetEdge(); //得到边的信息
void FindArticul(); //找关节点
void DFSArticul(int); //深度优先遍历图
VexBox v;
int count;
};
void ArtPoint::GetArtPoint() //接口函数
{
GetVexNode(); //得到顶点信息
GetEdge(); //得到边的信息
FindArticul(); //找关节点
}
void ArtPoint::GetVexNode() //得到顶点信息
{
cout << "Please Input The Name Of The Vertex :" << endl << endl;
char name;
while (cin >> name)
{
v.vexbox[v.vexnum++].name = name;
}
cin.clear();
}
void ArtPoint::GetEdge() //得到边的信息
{
cout << "Please Input The Two Nodes Which Made A Edge :" << endl << endl;
int t[2];
ChildNode *p, *newnode;
while (cin >> t[0] >> t[1])
{
for (int i = 0; i < 2; i++)
{
newnode = new ChildNode;
newnode->child = t[1 - i];
if ((p = v.vexbox[t[i]].firstchild) == NULL)
{
v.vexbox[t[i]].firstchild = newnode;
}
else
{
while (p->next != NULL)
{
p = p->next;
}
p->next = newnode;
}
}
}
cin.clear();
}
void ArtPoint::FindArticul() //找关节点
{
count = 1; //初始化count记录访问次序
v.vexbox[0].visitsq = 1;
DFSArticul(0); //从第一个节点开始访问
if (count < v.vexnum) //如果生成树的根有两颗或两颗以上子树
{
cout << v.vexbox[0].name << endl; //该节点为关节点输出之
}
for (int i = 1; i < v.vexnum; i++) //访问剩余未被访问的节点
{
if (v.vexbox[i].visitsq == 0)
{
DFSArticul(i);
}
}
}
void ArtPoint::DFSArticul(int n) //深度优先遍历图
{
//该节点的low值被定义为MIN{当前节点的访问次序,孩子节点的low值,祖先节点的访问次序}
int min = v.vexbox[n].visitsq = ++count; //初始化min
ChildNode *p = v.vexbox[n].firstchild;
while (p != NULL) //访问与该顶点有边相连的所有顶点
{
if (v.vexbox[p->child].visitsq == 0) //访问的是孩子节点
{
DFSArticul(p->child); //以该顶点开始深度优先遍历图
if (v.vexbox[p->child].low < min) //如果孩子节点的low值有小于min的
min = v.vexbox[p->child].low; //更新当前节点的low值
if (v.vexbox[p->child].low >= v.vexbox[n].visitsq) //如果孩子节点的low值大于等于当前节点的访问次序
//说明该树的根和子树中的其他节点均没有指向当前节点的祖先的节点
cout << v.vexbox[n].name << endl; //该节点为关节点
}
else if (v.vexbox[p->child].visitsq < min) //访问的是祖先节点//如有必要更新min
min = v.vexbox[p->child].visitsq;
p = p->next;
} //while
v.vexbox[n].low = min; //将获得的最小的min作为当前节点的low值
}
main.cpp
#include"head.h"
int main()
{
ArtPoint p;
p.GetArtPoint();
system("pause");
}