1. 最简单也是最直接的算法是,删除一个点然后判断连通性,如果删除此点,图不再连通,则此点是割点,反之不是割点(图的连通性一般通过深搜来判定,是否能一次搜索完 全部顶点);

  2. 通过深搜优先生成树来判定。从任一点出发深度优先遍历得到优先生成树,对于树中任一顶点V而言,其孩子节点为邻接点。由深度优先生成树可得出两类割点的特性:

    (1)若生成树的根有两棵或两棵以上的子树,则此根顶点必为割点。因为图中不存在连接不同子树顶点的边,若删除此节点,则树便成为森林;

    (2)若生成树中某个非叶子顶点V,其某棵子树的根和子树中的其他节点均没有指向V的祖先的回边,则V为割点。因为删去v,则其子树和图的其它部分被分割开来。

仍然利用深搜算法,只不过在这里定义visit[v]表示为深度优先搜索遍历图时访问顶点v的次序号,定义low[v]=Min{visit[v],low[w],visit[k]},其中w是顶点v在深度优先生成树上的孩子节点;k是顶点v在深度优先生成树上由回边联结的祖先节点。

割点判定条件:如果对于某个顶点v,存在孩子节点w且low[w]>=visit[v],则该顶点v必为关节点。因为当w是v的孩子节点时,low[w]>=visit[v],表明w及其子孙均无指向v的祖先的回边,那么当删除顶点v后,v的孩子节点将于其他节点被分割开来,从来形成新的连通分量。

#include<stdlib.h>
#include<stdio.h>
#include<stdbool.h>
/*--获取图的割点--*/
//使用邻接表作为图的存储结构
#define MAX_VERTEX_NUM 20  //图的最大顶点个数
typedef char VertexType;typedef struct ArcNode
{int adjvex;              //边指向的顶点位置 struct ArcNode *nextarc;  //指向下一条边的指针
}ArcNode;typedef struct VNode
{VertexType data;   //顶点名称ArcNode *firstarc; //指向第一条依附该顶点的边
}VNode,AdjList[MAX_VERTEX_NUM];typedef struct
{AdjList vertices;int vexnum,arcnum; //图的顶点数、边数
}ALGraph;//创建连通图
//确定图中顶点位置编号
int locateVex(ALGraph alg,char v)
{int i;for(i=0;i<alg.vexnum;i++){if(alg.vertices[i].data == v)return i;}return -1;} void createALGraph(ALGraph *alg)
{int i,j,k;char v1,v2;ArcNode *p,*s;printf("输入图的顶点数和边数\n");scanf("%d %d",&(alg->vexnum),&(alg->arcnum));getchar();printf("输入顶点名称\n");for(k=0;k<alg->vexnum;k++){printf("输入第%d个顶点",k);scanf("%c",&(alg->vertices[k].data));alg->vertices[k].firstarc = NULL;getchar();}printf("输入边的两个顶点v1 v2\n");for(k=0;k<alg->arcnum;k++){printf("输入第%d条边的两个顶点:",k);scanf("%c %c",&v1,&v2);getchar();i = locateVex(*alg,v1);j = locateVex(*alg,v2);//创建图为无向图,因此一条边依附两个顶点 p = (ArcNode*)malloc(sizeof(ArcNode));p->adjvex = j;p->nextarc = NULL;if(alg->vertices[i].firstarc == NULL){alg->vertices[i].firstarc = p;}else{s = alg->vertices[i].firstarc;while(s->nextarc!=NULL)s = s->nextarc;s->nextarc = p;}p = (ArcNode*)malloc(sizeof(ArcNode));p->adjvex = i;p->nextarc = NULL;if(alg->vertices[j].firstarc == NULL){alg->vertices[j].firstarc = p;}else{s = alg->vertices[j].firstarc;while(s->nextarc!=NULL)s = s->nextarc;s->nextarc = p;}   }
}//深度优先遍历图
bool visited[MAX_VERTEX_NUM];   //标记图的顶点是否被遍历,已遍历为true,否则为flase;void DFS(ALGraph G,int v)
{ArcNode *p;visited[v] = true;printf("%c ",G.vertices[v].data);for(p = G.vertices[v].firstarc;p!=NULL;p = p->nextarc){if(!visited[p->adjvex])DFS(G,p->adjvex);}} void DFSTraver(ALGraph G)
{printf("图的深度优先遍历序列:\n");int i;for(i=0;i<G.vexnum;i++)visited[i] = false;for(i=0;i<G.vexnum;i++)if(!visited[i])DFS(G,i);
}//获取图的关节点(割点)
int visit[MAX_VERTEX_NUM],low[MAX_VERTEX_NUM],count;
void DFSArticul(ALGraph G, int v)
{int min,w;ArcNode *p;visit[v] = min = count++;  //v是第count个访问的顶点]for(p = G.vertices[v].firstarc;p!=NULL;p = p->nextarc)      //对v的每个邻接顶点检查 {w = p->adjvex;   //w为v的邻接顶点if(visit[w]==0)   //w未曾访问是v的孩子 {DFSArticul(G,w);  //返回求low[w] if(low[w] < min)min = low[w];if(low[w] >= visit[v])printf("%d--%c\n",v,G.vertices[v].data);}else if(visit[w] < min)   //w已访问,w是v的生成树上的祖先 {min = visit[w];}} low[v] = min;} void findArticul(ALGraph G)
{printf("图的关节点(割点):\n"); int i,v;ArcNode *p;count = 1;visit[0] = 1;    //设置邻接表上0号顶点为生成树的根 for(i=1;i<G.vexnum;i++)visit[i] = 0;            //其余顶点尚未访问p = G.vertices[0].firstarc;v = p->adjvex;DFSArticul(G,v); //从第v个顶点出发深度优先查找关节点if(count < G.vexnum)  //生成树的根至少有两棵子树 {printf("0--%c\n",G.vertices[0].data);  //根是关节点,输出 while(p->nextarc){p = p->nextarc;v = p->adjvex;if(visit[v]==0)DFSArticul(G,v);}}
}
int main()
{ALGraph alg;createALGraph(&alg);DFSTraver(alg);printf("\n");findArticul(alg);printf("\n");return 0;
}

求连通图的关节点(割点)--C语言相关推荐

  1. LU分解法c语言程序设计,矩陣LU分解求逆详细分析与C语言实现.doc

    矩陣LU分解求逆详细分析与C语言实现 题目要求 给定一个多维矩阵,实现该矩阵的求逆运算. 1.理论分析 矩阵的一种有效而广泛应用的分解方法是矩阵的LU三角分解,将一个n阶矩阵A分解为一个下三角矩阵L和 ...

  2. 求素数的三大算法 —— C 语言 篇

    求素数的三大算法 -- C 语言 篇 文章目录 求素数的三大算法 -- C 语言 篇 算法一 :暴力遍历 思路: 代码: 算法二:折半范围遍历 思路: 代码: 算法三:根号范围遍历 思路: 代码: 总 ...

  3. C语言编程求仙,求21位凌波仙子数(C语言实现)

    求21位水仙花数(C语言实现) /* * 21位水仙花数 */ #include #include #include #define DIGIT 21 char pow[DIGIT][50]={0}; ...

  4. c语言编写程序计算行列式值,求行列式的值,用C语言怎么写啊? 如何求行列式的值...

    导航:网站首页 > 求行列式的值,用C语言怎么写啊? 如何求行列式的值 求行列式的值,用C语言怎么写啊? 如何求行列式的值 相关问题: 匿名网友: 行列式计算公式知道吧,给你个源码参考,大一时写 ...

  5. Java实现无向连通图中的“割点”问题

    直接上代码,详细请见注释或者下方留言. package cut.point;import java.util.Scanner; import java.util.Stack;/*** "轰炸 ...

  6. 超详细Tarjan算法总结,求强连通分量,割点,割边,有重边的割边

    Tarjan是一个人,他一身中发明了很多算法,就这几个算法最为出名. 1.求有向图的强连通分量,那么什么是强连通分量呢,就是一个顶点集合,任意两个顶点间都可以互相到达.一个顶点也是强联通分量如果图中任 ...

  7. c++ 求四边形面积和周长_C语言编程题 题目:任意输入4个点,求围成四边形的面积是多少?...

    C语言编程题:任意输入4个点,求围成四边形的面积是多少.代码如下: #include "stdio.h" #include "math.h" void main ...

  8. python输入一个正整数n求下列算式的值_C语言编写程序:输入一个正整数x和一个正整数n,求下列算式的值。,C语言 编写一个程序,输入一个正整数,求出它是几位数。...

    导航:网站首页 > C语言编写程序:输入一个正整数x和一个正整数n,求下列算式的值.,C语言 编写一个程序,输入一个正整数,求出它是几位数. C语言编写程序:输入一个正整数x和一个正整数n,求下 ...

  9. 弦截法c语言程序,高数介质定理——弦截法求根代码实践(C语言)

    在高等数学中,我们一开始接触概念时就接受了ε-δ(epsilon-delta)语言的洗礼,但即使到课程的结束,许多人依然会对各种抽象的数学符号.定理证明感到无所适从,我也不例外,尽管在写这篇博客以前已 ...

最新文章

  1. 如何区分直连串口线和交叉串口线?
  2. Gamma校正及其OpenCV实现
  3. elasticsearch和mysql排序问题
  4. 使用python简单连接并操作数据库
  5. 如何在 C# 中使用 RabbitMQ
  6. 论文学习6-(M2DNE)Temporal Network Embedding with Micro- and Macro-dynamics
  7. centos 搭建Jenkins
  8. Java Map 自定义排序
  9. python unittest断言_python接口自动化(二十四)--unittest断言——中(详解)
  10. 项目常用工具类整理(一)--时间工具类DateUtil.java
  11. 一路PN码串行捕获设计--基于《通信收发信机的verilog实现与仿真》实例
  12. Kindle PaperWhite 3 5.8.10越狱成功!
  13. 教你用Python 做PPT之制作动态图~做出来的效果高级又好看
  14. arcgis10之将一个shp属性数据通过某一字段将要素属性关联至另一shp文件中
  15. CAD二次开发合并所有能合并的线
  16. C语言程序设计作业——摘苹果
  17. 企业网盘到底应该怎么选?
  18. 去掉浏览器页面广告和弹窗
  19. HTML+CSS基础学习
  20. SSM上传图片并保存图片地址到数据库

热门文章

  1. 数据社区推荐—恒有数(UData)
  2. 【游戏客户端】聊天排行榜朋友圈系统实现机制
  3. pyqt5多窗口来回切换
  4. 全球首个人工智能实验床“泰”在深圳发布
  5. CVPR2022论文速递(2022.4.20)!共13篇!
  6. pyqt5 商店小票打印的实现模板
  7. 拒绝黄牛 《东方早报》记者在太平洋数码遭殴
  8. 使用 EasyCV Mask2Former 轻松实现图像分割
  9. 网页版MC服务器搭建+汉化
  10. Git命令之批量分支