题目:求一个连通图的割点,割点的定义是,如果除去此节点和与其相关的边,图不再连通,描述算法。

分析:

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

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

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

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

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

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

#include <iostream>
#include <string>
#include <queue>
using namespace std;  #define MAXN 100  struct ArcNode
{  int adjVertex;       //边到的顶点  ArcNode *next;
};  struct VNode
{  string data;  ArcNode *firstArc;
};  typedef VNode AdjList[MAXN];  struct Graph
{  int vertexNum;  int arcNum;  AdjList vertexs;
};  int Locate(Graph g,string str)
{  for(int i = 0;i<g.vertexNum;i++)  {  if(str == g.vertexs[i].data)  return i;  }  return -1;
}  void Create(Graph &g)
{  string start,end;  cout << "请输入顶点和边数:"<<endl;  cin>>g.vertexNum>>g.arcNum;  for(int i = 0;i<g.vertexNum;i++)  {  cout<<"请输入第"<<i<<"个顶点:"<<endl;  cin>>g.vertexs[i].data;  g.vertexs[i].firstArc = NULL;  }  for(int i = 0;i <g.arcNum;i++)  {  cout<<"请输入第"<<i<<"条边的起始和结束顶点"<<endl;  cin>>start>>end;  int m = Locate(g,start);  int n = Locate(g,end);  ArcNode *node = new ArcNode;  node->adjVertex = n;  node->next = g.vertexs[m].firstArc;  g.vertexs[m].firstArc = node;  ArcNode *node1 = new ArcNode;  node1->adjVertex = m;  node1->next = g.vertexs[n].firstArc;  g.vertexs[n].firstArc = node1;  }
}  void Print(Graph g)
{  for(int i = 0;i<g.vertexNum;i++)  {  cout << g.vertexs[i].data;  ArcNode *p = g.vertexs[i].firstArc;  while(p)  {  cout<<"-->"<<g.vertexs[p->adjVertex].data;  p = p->next;  }  cout <<endl;  }
}  int FirstAdjVex(Graph g,int v)//返回v的第一个邻接顶点序号
{  ArcNode *p = g.vertexs[v].firstArc;  if(p!= NULL)  return p->adjVertex;  else  return -1;
}  int NextAdjVex(Graph g,int v,int w) //返回顶点v相对于w的下一个邻接点的序号
{  ArcNode *p = g.vertexs[v].firstArc;  while(p)  {  if(p->adjVertex == w)  break;  p = p->next;  }  if(p->adjVertex !=w || !p->next)  return -1;  return p->next->adjVertex;
}  //求割点
int countN;
int visted[MAXN];
int low[MAXN];  void DFSCutPoint(Graph g,int v0)
{  int min = 0,w;  visted[v0] = min = ++countN;;//v0是第count个访问的顶点,min的初值为visited[v0],即v0的访问次序   for(ArcNode *p = g.vertexs[v0].firstArc;p;p=p->next)  {  w = p->adjVertex;  if(!visted[w])  {  DFSCutPoint(g,w);//从第w个顶点出发深搜,查找并输出关节点(割点),返回前求得low[w]    if(low[w] < min)//如果v0的孩子节点w的low[]小,说明孩子节点还与其他节点(祖先)相邻    min = low[w];  if(low[w]>=visted[v0] ) //v0的孩子节点w只与v0相连,则v0是关节点(割点)    cout<<g.vertexs[w].data<<" ";  }  else if(visted[w] < min)//w已访问,则w是v0生成树上祖先,它的访问顺序必小于min    min =visted[w];  }  low[v0] = min;//low[v0]取三者最小值
}  void FindCutPoint(Graph g)
{  visted[0] = true;  for(int i = 1;i<g.vertexNum;i++)  visted[i] = false;  ArcNode *p=g.vertexs[0].firstArc;  int v = p->adjVertex;  DFSCutPoint(g,v);  if(countN < g.vertexNum)  {  cout << g.vertexs[0].data<<" ";  while(p->next)  {  p = p->next;  v = p->adjVertex;  if(!visted[v])  DFSCutPoint(g,v);  }  }
}  int main()
{  Graph g;  Create(g);  cout<<"割点如下: "<<endl;    FindCutPoint(g);  return 0;  

转载于:https://www.cnblogs.com/tham/p/6827246.html

求一个连通图的割点(去掉一个点后图不再连通)相关推荐

  1. java并查集判断是否是连通图_并查集-判断图的连通

    首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的.最后要解决的是整幅图的连通性问题.比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分 ...

  2. python去掉最高分和最低分_去掉一个最高分,去掉一个最低分求平均值(trimmean)...

    如下图: 演讲比赛,要求去掉一个最高分,去掉一个对低分后求平均值.当然这个太简单了,我们可以用max求出最大值,用min求出最小值,然后sum求出数据总和,用(总和-最大值-最小值)/(数据总个数-2 ...

  3. c语言只能最大值不能最小值,用c语言编写输入10个无序的整数,去掉一个最大值和最小值,然后求其平均值...

    用c语言编写"输入10个无序的整数,去掉一个最大值和最小值,然后求其平均值"以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我 ...

  4. 在歌唱比赛中,共有10位评委进行打分(0-100分的区间),在计算歌手得分时, 去掉一个最高分,去掉一个最低分,然后剩余的8位评委的分数进行平均, 就是该选手的最终得分。输入每个评委的评分,求某选

    package kaoshi3; import java.util.Scanner; /**  * 在歌唱比赛中,共有10位评委进行打分(0-100分的区间),在计算歌手得分时,  去掉一个最高分,去 ...

  5. python去掉一个最高分和最低分求平均数_excel去掉一个最高分和最低分求平均数 - 卡饭网...

    怎么快速计算考试成绩的最高分.最低分.平均分? 怎么快速计算考试成绩的最高分.最低分.平均分? 我们可以使用Excel工作表快速计算出学校考试成绩的最高分.最低分和平均分,不需要逐个计算和核查,下面就 ...

  6. n个评委给m个选手打分python_青年歌手参加歌曲大奖赛计分系统:有N个评委进行打分,求这位选手的平均得分(去掉一个最高分和一个最低分...

    问题描述: 青年歌手参加歌曲大奖赛计分系统:有N个评委进行打分,求这位选手的平均得分(去掉一个最高分和一个最低分 我写的是10个评委的,可输出的结果和用计算器算出的不一样...各位大神请在我的源程序上 ...

  7. C语言:编程题(在某次比赛中,有10个评委给选手打分。现要求编程:1)输入一位选手的10个成绩;2)去掉一个最高分,一个最低分,求出平均成绩;3)输出该选手的平均成绩,保留一位小数。

    具体如下: 编程题(在某次比赛中,有10个评委给选手打分.现要求编程:1)输入一位选手的10个成绩:2)去掉一个最高分,一个最低分,求出平均成绩:3)输出该选手的平均成绩,保留一位小数.(17分) 基 ...

  8. 歌咏比赛,有10个评委,有5个选手,求出每一个选手的平均得分(去掉一个最高分和一个最低分)。 要求:利用数组、有参有返回的函数

    歌咏比赛,有10个评委,有5个选手,求出每一个选手的平均得分(去掉一个最高分和一个最低分). 要求:利用数组.有参有返回的函数 judge = []player = []avg = 0sum = 0m ...

  9. Java:学校比赛现场有10个评委,要求从键盘输入10个分数作为评委对一名选手的打分,评分规则为去掉一个最高分,去掉一个最低分,求该名选手平均分,打印到控制台。

    Java练习: 学校比赛现场有10个评委,要求从键盘输入10个分数作为评委对一名选手的打分,评分规则为去掉一个最高分,去掉一个最低分,求该名选手平均分,打印到控制台. 代码如下: package co ...

最新文章

  1. 如何解决:“ UnicodeDecodeError:#39;ascii#39;编解码器无法解码字节”
  2. pycharm中导入allure提示模块不存在解决方法
  3. 恢复从回收站中被删除的文件的方法
  4. Java 内存分配——Thinking in Java 4th 读书笔记
  5. 【做题】TCSRM601 Div1 500 WinterAndSnowmen——按位考虑dp
  6. tab使用 TabActivity TabHost Tabspec常用方法
  7. springMvc 注解@JsonFormat 日期格式化
  8. 【GitLab】与idea的搭配
  9. MSP430G2553 移植 Contiki RTOS 实时操作系统
  10. Python文件拷贝函数
  11. scala基础之提取器extractor
  12. Servlet之前端web数据与后台Java数据进行交互
  13. php开发Hive Web查询
  14. Eclipse 使用 SVN 插件后修改用户方法汇总
  15. Spring Boot 2 (三):Spring Boot 开源软件都有哪些?
  16. 范德蒙行列式计算以应用
  17. Mac电脑无法从Photoshop 2020作为插件访问DeNoise AI的解决办法
  18. iphone禁止自动连接wifi操作方法「苹果教程」
  19. pycharm更换国内源
  20. 【CTF】咏春招新赛收获兼write up

热门文章

  1. 2018ACM/ICPC亚洲区域赛(焦作)F. Honeycomb
  2. 利用cookies跳过登陆验证码
  3. == vs === in Javascript
  4. Linux安装Jenkins
  5. iOS开发中@property的属性weak nonatomic strong readonly等介绍
  6. Arcengine 基本操作(待更新)
  7. 张小二:做一个幸福的胖子
  8. python根据文件路径获取上级目录路径
  9. vue-cli webpack 打包报错:Unexpected token: punc (()
  10. linux如何记录测试时长,如何测试Linux命令运行时间?