Light OJ - 1026 - Critical Links(图论-Tarjan算法求无向图的桥数) - 带详细注释
无向连通图中,如果删除某边后,图变成不连通,则称该边为桥。
也可以先用Tajan()进行dfs算出所有点 的low和dfn值,并记录dfs过程中每个 点的父节点;然后再把所有点遍历一遍, 看其low和dfn,满足dfn[ fa ]<low[ i ](0<i<=n, i 的 father为fa) —— 则桥为fa-i。 找桥的时候,要注意看有没有重边;有重边,则不是桥。
另外,本题的题意及测试样例中没有重边,所以不用考虑重边。
带详细注释的题解:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<stack>
#include<vector>
#define maxn 10010
using namespace std;
int dfn[maxn],low_link[maxn] ,Father[maxn];
//tarjan 算法的dfn ——在DFS过程中 的访问序号(也可以叫做开始时间
//tarjan 算法的low_link[i]——从i节点出发DFS过程中i下方节点所能到达的最早的节点的 开始时间
int bridgenum, Time ,n ; //桥的总数,dfn时间戳,n为顶点数,
vector<int>G[maxn]; //定义图的邻接矩阵表
stack<int>st;
struct node{
int u,v;
}bridge[maxn]; //整个图的桥的存储
bool cmp( node a,node b )
{
if(a.u!=b.u)return a.u<b.u;
else return a.v<b.v;
}
void init(){
int i;
for(i=;i<=n;i++) //初始化邻接表
G[i].clear();
bridgenum=;Time=;
memset(dfn,,sizeof(dfn));
memset(low_link,,sizeof(low_link));
memset(Father,,sizeof(Father));
}
void tarjan(int u,int fa)
{
low_link[u]=dfn[u]=++Time;
Father[u]=fa; //记录父节点
// st.push(u);
for(int i=;i<(int)G[u].size();i++){
int v=G[u][i];
if(!dfn[v]){
tarjan(v,u);
low_link[u]=min(low_link[u],low_link[v]);
}
else if(v!=fa){ //不能连接到父节点!
low_link[u]=min(low_link[u],dfn[v]);
}
else{
//这种情况就是有重边的情况!不予处理,直接跳过!
}
}
}
void solve()
{
for(int i=;i<n;i++){
if(!dfn[i])
tarjan(i,-);
}
int ans=;
for(int i=;i<n;i++){
int v=Father[i];
if(dfn[v]<low_link[i]&&v!=-){ //若v-i可以构成父节点
bridge[ans].u=v; //桥的两条边
bridge[ans].v=i;
if(bridge[ans].u>bridge[ans].v)
swap(bridge[ans].u,bridge[ans].v);
ans++;
}
}
sort(bridge,bridge+ans,cmp);
printf("%d critical links\n",ans);
for(int i=;i<ans;i++){
printf("%d - %d\n",bridge[i].u,bridge[i].v);
}
}
int cal_num(char ch[]){
int len=strlen(ch),s=;
for(int i=;i<=len-;i++){
s=s*+ch[i]-'';
}
return s;
}
int main()
{
int T,cas=;
scanf("%d",&T);
while(T--)
{
init();
char ch[];
int m ,u,v; //边数
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d%s",&u,ch);
m=cal_num(ch); //截取出数字存入m——边数
for(int j=;j<=m;j++){
scanf("%d",&v);
G[u].push_back(v); //这里按单向边任意一边存储就可以了,毕竟是无向图!
G[v].push_back(u);
}
}
printf("Case %d:\n",++cas);
solve();
}
return ;
}
Light OJ - 1026 - Critical Links(图论-Tarjan算法求无向图的桥数) - 带详细注释的更多相关文章
- tarjan算法求无向图的桥、边双连通分量并缩点
// tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...
- Light OJ 1026 - Critical Links (图论-双向图tarjan求割边,桥)
题目大意:双向联通图, 现在求减少任意一边使图的联通性改变,按照起点从小到大列出所有这样的边 解题思路:双向边模版题 tarjan算法 代码如下: #include<bits/stdc++.h& ...
- [Tarjan系列] Tarjan算法求无向图的桥和割点
RobertTarjan真的是一个传说级的大人物. 他发明的LCT,SplayTree这些数据结构真的给我带来了诸多便利,各种动态图论题都可以用LCT解决. 而且,Tarjan并不只发明了LCT,他对 ...
- [Tarjan系列] Tarjan算法求无向图的双连通分量
这篇介绍如何用Tarjan算法求Double Connected Component,即双连通分量. 双联通分量包括点双连通分量v-DCC和边连通分量e-DCC. 若一张无向连通图不存在割点,则称它为 ...
- tarjan算法--求无向图的割点和桥
一.基本概念 1.桥:是存在于无向图中的这样的一条边,如果去掉这一条边,那么整张无向图会分为两部分,这样的一条边称为桥无向连通图中,如果删除某边后,图变成不连通,则称该边为桥. 2.割点:无向连通图中 ...
- SPF Tarjan算法求无向图割点(关节点)入门题
SPF 题目抽象,给出一个连通图的一些边,求关节点.以及每个关节点分出的连通分量的个数 邻接矩阵只要16ms,而邻接表却要32ms, 花费了大量的时间在加边上. // time 16ms 1 ...
- tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)
基本概念 给定无向连通图G = (V, E)割点:对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点割边(桥)若对于e∈E,从图中删去边e之后,G分 ...
- Tarjan算法求割点
(声明:以下图片来源于网络) Tarjan算法求出割点个数 首先来了解什么是连通图 在图论中,连通图基于连通的概念.在一个无向图 G 中,若从顶点i到顶点j有路径相连(当然从j到i也一定有路径),则称 ...
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)
Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...
随机推荐
- Python3-ibm_db模块-数据库操作之DB2
官方文档 https://www.ibm.com/support/knowledgecenter/SSEPGG_9.5.0/kc_gen/developing-gen1.html 模块安装 Windo ...
- Vue + ElementUI的电商管理系统实例01 登录表单
效果图: 1.首先来根据Element网站实现布局: <template> <div class="login_container"> <div cl ...
- linux中信号的API详解实例
/************************************************************************* > File Name: signal.c ...
- java绘图(基于Graphics2D)
1.绘图基本操作 请参考下面基础示例: int width = 200, height = 250; //创建图片对象 BufferedImage image = new BufferedImage( ...
- [转帖]EPOLL和IOCP比较
EPOLL和IOCP比较 https://blog.csdn.net/educast/article/details/15503179 IOCP 异步非阻塞EPOLL 异步阻塞 EPOLL是半成品 ...
- C++ 中 static 与 const 的用法及对比
在这个学习过程中我对 static 及 const 的使用时常会混淆,因此整理,加深记忆 一.类的静态成员 如果某个属性为整个类所共有,不属于任何一个具体对象,则采用 static 关键字来声明静态成 ...
- WUSTOJ 1349: TLE(Java)算法优化
题目链接:1349: TLE Description WH在刷题时,设计出了如下代码: #include<stdio.h> int main() { int i, j, cnt, k, N ...
- PB笔记之第一行数据不能删除的解决方法
如果第一行数据不能删除,则单独写SQL进行删除 window lw_sheet //dw_1.event pfc_deleterow()long i String ls_manidInteger ls ...
- es6☞对象的解构赋值
变量必须与属性同名 let {name, age} = {name: 'wang', age: 22}; console.log(name, age); //wang 22 let {name} = ...
- [Done] Codeforces Round #562 (Div. 2) 题解
A - Circle Metro 模拟几百步就可以了. B - Pairs 爆搜一下,时间复杂度大概是 $O(4 * n)$ Code: 56306723 C - Increasing by Modu ...