一、定义:

维基百科:

二、代码:

#include<iostream>
#include<list>
#include<algorithm>using namespace std;#define NIL -1class Graph
{int n;list<int> *adj;void bridgeUtil(int u,bool visited[], int disc[],int low[], int parent[], int &time);
public:Graph(int _n){   n = _n;    adj = new list<int>[_n];  }~Graph(){ delete [] adj; } void addEdge(int v, int w){ adj[v].push_back(w);   adj[w].push_back(v); } void bridge();       //提供给外部调用,完成一些初始化作用,再调用bridgeUtil()
};

bridgeUtil形参说明:
u:要处理的下一个顶点
visited[]:标记是否被访问
disc[]:disc[u]第一次被访问的时间(顶点在DFS生成树中的次序)
low[]:low[u]存顶点u能够达到的最早的祖先(disc值最小的祖先),
一开始先初始化u第一次被访问的时间,除非在邻居中找到了它的祖先(已经被访问过了,双亲这里不算)
parent[]:parent[u]记录u的双亲
time:时间戳,传的引用

void Graph::bridgeUtil(int u, bool visited[], int disc[],int low[], int parent[], int &time)
{disc[u] = low[u] = ++time;visited[u] = true;list<int>::iterator it;for(it = adj[u].begin(); it != adj[u].end(); it++){int v = *it;if(!visited[v]){parent[v] = u;bridgeUtil(v,visited,disc,low,parent,time);low[u] = min(low[u], low[v]);if(low[v] > disc[u])      //是桥 {cout<<u<<"-->"<<v<<endl;}}else if( v != parent[u]){low[u] = min(low[u], disc[v]); }}
}
void Graph::bridge()
{bool *visited = new bool[n];int *parent = new int[n];    int *disc = new int[n];int *low = new int[n];for(int i = 0; i < n; i++){visited[i] = false;parent[i] = NIL; }int time = 0;for(int i = 0; i < n; i++){if(!visited[i]){bridgeUtil(i,visited,parent,disc,low,time);}}
}

和找图的关节点思想是一样的,只是判断是不是关节点的时候用parent[v]!=-1 && low[v]>=disc[u]来判断,这里用low[v] > disc[u]来判断。
另外跟找有向图的强连通分量的Tarjan算法也是一个思想。

三、测试:

#include<iostream>
#include<list>
#include<algorithm>using namespace std;#define NIL -1class Graph
{int n;list<int> *adj;void bridgeUtil(int u,bool visited[], int disc[],int low[], int parent[], int &time);
public:Graph(int _n){   n = _n;    adj = new list<int>[_n];  }~Graph(){ delete [] adj; } void addEdge(int v, int w){ adj[v].push_back(w);   adj[w].push_back(v); } void bridge();
};
/*
形参说明:
u:要处理的下一个顶点
visited[]:标记是否被访问
disc[]:disc[u]第一次被访问的时间(顶点在DFS生成树中的次序)
low[]:low[u]存顶点u能够达到的最早的祖先(disc值最小的祖先),
一开始先初始化u第一次被访问的时间,除非在邻居中找到了它的祖先(已经被访问过了,双亲这里不算)
parent[]:parent[u]记录u的双亲
time:时间戳,传的引用*/
void Graph::bridgeUtil(int u, bool visited[], int disc[],int low[], int parent[], int &time)
{disc[u] = low[u] = ++time;visited[u] = true;list<int>::iterator it;for(it = adj[u].begin(); it != adj[u].end(); it++){int v = *it;if(!visited[v]){parent[v] = u;bridgeUtil(v,visited,disc,low,parent,time);low[u] = min(low[u], low[v]);if(low[v] > disc[u])      //是桥 {cout<<u<<"-->"<<v<<endl;}}else if( v != parent[u]){low[u] = min(low[u], disc[v]); }}
}
void Graph::bridge()
{bool *visited = new bool[n];int *parent = new int[n];int *disc = new int[n];int *low = new int[n];for(int i = 0; i < n; i++){visited[i] = false;parent[i] = NIL; }int time = 0;for(int i = 0; i < n; i++){if(!visited[i]){bridgeUtil(i,visited,parent,disc,low,time);}}
}
int main()
{ // Create graphs given in above diagrams cout << "\nBridges in first graph \n"; Graph g1(5); g1.addEdge(1, 0); g1.addEdge(0, 2); g1.addEdge(2, 1); g1.addEdge(0, 3); g1.addEdge(3, 4); g1.bridge(); cout << "\nBridges in second graph \n"; Graph g2(4); g2.addEdge(0, 1); g2.addEdge(1, 2); g2.addEdge(2, 3); g2.bridge(); cout << "\nBridges in third graph \n"; Graph g3(7); g3.addEdge(0, 1); g3.addEdge(1, 2); g3.addEdge(2, 0); g3.addEdge(1, 3); g3.addEdge(1, 4); g3.addEdge(1, 6); g3.addEdge(3, 5); g3.addEdge(4, 5); g3.bridge(); return 0;
}

图论---桥(割边)相关推荐

  1. 图论:桥(割边)和割点

    文章目录 桥 定义 性质 寻找桥 查找桥使用了深度优先遍历(DFS),可否使用广度优先遍历(BFS)? -> 不能! 割点 定义 性质 查找割点 桥 定义 对于无向图,如果删除了一条边,**整个 ...

  2. tarjan求割点和桥(割边)模板

    tanjan算法相关概念 为了与有向图尽可能保持一致,我们将无向图的一条无向边拆分成两条单向边.两条边互为反向边. 从图中一点作为起点,进行DFS搜索遍历图,这样会得到一棵树,我们称之为DFS搜索树, ...

  3. 0x66.图论 - Tarjan算法与无向图连通性

    目录 一.无向图的割点与桥 割点 桥/割边 时间戳 搜索树 追溯值 二.割边判定法则 三.割点判定法则 1.luogu P3388 [模板]割点(割顶) 2.luogu P3469 [POI2008] ...

  4. tarjan求桥、割顶

    若low[v]>dfn[u],则(u,v)为割边.但是实际处理时我们并不这样判断,因为有的图上可能有重边,这样不好处理.我们记录每条边的标号(一条无向边拆成的两条有向边标号相同),记录每个点的父 ...

  5. 图论(三)距离与连通性

    G偏心距e(v):结点v和它相距最远的结点的距离. 偏心结点:若结点w满足d(W,V)= e(V),称w为v的偏心结点,偏心结点并不是相互的. 互为偏心的:两个结点一个都是另一个的偏心结点. 半径ra ...

  6. 第十三章 欧拉图与哈密顿图(图论)

    文章目录 第十三章 欧拉图与哈密顿图 13.1 欧拉图 Euler 6.2 哈密顿图 Hamiltonian 第十三章 欧拉图与哈密顿图 13.1 欧拉图 Euler 引入:哥尼斯堡的普雷格尔(Pre ...

  7. `Computer-Algorithm` 算法术语,自定义算法术语

    Contents 图论 定义 某点的搜索图 某点的极限路径 数论 算法术语缩写 数论 @Delimiter(Old) 图论 DFS图 树Tree 有向图DiG 有向无环图DAG 基础概念 无向图UnG ...

  8. Tarjan(原理、应用)

    目录 Tarjan 一.算法介绍 二.原理 三.应用 1.求强连通分量 例1 [[POJ 3180]](http://poj.org/problem?id=3180) The Cow Prom 例2 ...

  9. 并查集算法总结专题训练

    并查集算法总结&专题训练 1.概述 2.模板 3.例题 1.入门题: 2.与别的算法结合: 3.考思维的题: 4.二维转一维: 5.扩展域并查集&边带权并查集: 4.总结 1.概述 并 ...

最新文章

  1. [JAVA EE] Thymeleaf 常用工具类
  2. 全球支付平台paypal社招一面,二面合并面经
  3. 报告视频录制:腾讯会议录屏+人像画中画特效
  4. 联想筹资13.5亿美元 支付收购摩托罗拉移动剩余款
  5. 关于模型复杂度的一个想法
  6. 解决win10资源管理器右键菜单卡死问题
  7. 观察者模式在源码中的应用
  8. PC寄存器为什么会被设定为线程私有
  9. 编程语言入门及进阶、设计模式、面向对象书籍
  10. 智能优化算法:金枪鱼群优化算法-附代码
  11. 中国科学院大学数学院本科生教材
  12. chitubox micromake L3+ 切片软件配置对应关系
  13. 谷歌开源 Embedding Projector 高维数据可视化--转自开源中国
  14. Spark机器学习库简介
  15. matlab仿真光学拍,用matlab研究光学拍
  16. 时钟系统安装配置注意事项
  17. paraview热流图(1):添加glyphs
  18. Pr视频剪辑——自我学习
  19. Unity3d--坦克对战游戏 AI 设计
  20. CentOS 7 快速搭建JavaWeb开发环境并部署Spring boot项目(纯干货、详细)

热门文章

  1. python爬虫怎么挣钱-月薪45K的Python爬虫工程师告诉你爬虫应该怎么学,太详细了!...
  2. python与office结合可以干什么-震惊!当Python遇到Excel后,将开启你的认知虫洞
  3. python简单爬虫代码-使用Python3.5写简单网络爬虫
  4. python基本代码教程-Python入门教程丨1300多行代码,让你轻松掌握基础知识点
  5. python必备入门代码-初学必备:1分钟带你认识Python的代码(上)
  6. python 菜鸟-Python3 教程
  7. python零基础能学吗-python 零基础该怎么学?
  8. python能做什么工作-学完Python我们可以做什么工作?
  9. python就业方向-Python的5大就业方向,薪资诱人前景好!
  10. python能做什么软件-初学python编程,有哪些不错的软件值得一用?