关节点算法
本篇文章将贴出,基于深度优先遍历计算关节点数量的代码,并附带一定的讲解,可供大家参考学习,本来想从CSDN抄一份代码的,结果这里代码太长了,效果看起来也不怎么样
特别鸣谢 :在我想算法时获得BUFF《了了的祝福》,居然真的有用,
当然,代码主题部分与CSDN能找到的一个关节点数量求解问题的代码接近,确实借鉴了,但他对于最后根节点是否是关节点的判断有误,这里是修正版。
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
一、什么是关节点?
在一个无向连通图G(V, E)中,可能存在某个(或多个)结点 a,使得一旦删除 a 及其相关联的边,图G将不再是连通图,则称结点 a 为图G的关节点。
二、
1.代码贴图
算了不简介了,大家应该都看过算法了,不然不会做这种题,我就划个水,我猜大家大部分是来找代码的
#include <iostream>
using namespace std;
struct ENode {
int adjVex;
ENode* nextArc;
};
ENode** a;//邻接表声明
int tm = 0;
int d[100], low[100];//两个辅助数组,d[u]记录结点u被访问的时间,
//low[u]是u的最低深度优先数,
int sum = 0;//记录关节点数量
int parent[100];//parent[u]记录u的父节点
int cotl = 0;//用来判断根节点是不是关节点
void DFS(int u, int p) {//深度优先遍历,过程中补上d,low,parent数组的值
ENode* w;
low[u] = d[u] = tm++;
for (w = a[u]; w; w = w->nextArc) {
int v = w->adjVex;
if (u == 0 && w != a[0] && d[v] == -1)cotl++;//判断根结点是不是关节点
if (d[v] == -1)
{
DFS(v, u);
if (low[u] > low[v])
low[u] = low[v];
}
else if (v != p && low[u] > d[v])
low[u] = d[v];
else if (v == p)
parent[u] = v;
}
}
void Sum(int n) {//通过遍历每一个结点i,每个结点和他的每一个孩子j比较,
//low[j] >= d[i]表示i是关节点,或者是根
//注意是从1开始,代表直接略过根没有判断,所以i必定是关节点
int i, j;
for (i = 1; i < n; i++) {
for (j = 1; j < n; j++) {
if (parent[j] == i) {
if (low[j] >= d[i]) {
sum++;
break;
}
}
}
}
}
int main() {
int i;
int cot = 0;
int n, e;
int u, v;
ENode* t;
cin >> n >> e;
a = new ENode * [n];
for (i = 0; i < n; i++)//初始化
a[i] = NULL;
for (i = 0; i < e; i++) {//建立邻接表
cin >> u >> v;
t = new ENode;
t->adjVex = v;
t->nextArc = a[u];
a[u] = t;
t = new ENode;
t->adjVex = u;
t->nextArc = a[v];
a[v] = t;
}
for (i = 0; i < n; i++)//初始化
{
d[i] = -1;
parent[i] = -1;
}
DFS(0, -1);//第一个参数u是当前访问结点,第二个参数p是u的父节点
Sum(n);//计算根节点数量
if (cotl > 0)sum++;//对根结点进行判断,是否是关节点。
cout << sum << endl;
return 0;
}
2.特别解析
对于我对根结点的判断方法:
if (u == 0 && w != a[0] && d[v] == -1)cotl++;
u == 0表示当先访问的是根节点(因为你做邻接表当然都是以0开头,自然用0做根节点,注意这里虽然用了DFS形成树,但本质上还是一个图,所以根结点的选择对结果并没有影响)
w != a[0] 表示当前访问的分支,不是根结点的第一个分支,如下图(a)有根结点有两个分支 ,(b)只有一个分支。
d[v] == -1,表示当前访问结点未被访问过,
总的来说就是,如果根结点不是关节点,那么从他第一个分支开始深度优先遍历时,其他分支上的结点应该都被访问过了,如果没被访问,说明根结点是连接这一分支与第一分支的唯一通道,符合关节点定义。