原题链接

    无向连通图中,如果删除某边后,图变成不连通,则称该边为桥。

  也可以先用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算法求无向图的桥数) - 带详细注释的更多相关文章

  1. tarjan算法求无向图的桥、边双连通分量并缩点

    // tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...

  2. Light OJ 1026 - Critical Links (图论-双向图tarjan求割边,桥)

    题目大意:双向联通图, 现在求减少任意一边使图的联通性改变,按照起点从小到大列出所有这样的边 解题思路:双向边模版题 tarjan算法 代码如下: #include<bits/stdc++.h& ...

  3. [Tarjan系列] Tarjan算法求无向图的桥和割点

    RobertTarjan真的是一个传说级的大人物. 他发明的LCT,SplayTree这些数据结构真的给我带来了诸多便利,各种动态图论题都可以用LCT解决. 而且,Tarjan并不只发明了LCT,他对 ...

  4. [Tarjan系列] Tarjan算法求无向图的双连通分量

    这篇介绍如何用Tarjan算法求Double Connected Component,即双连通分量. 双联通分量包括点双连通分量v-DCC和边连通分量e-DCC. 若一张无向连通图不存在割点,则称它为 ...

  5. tarjan算法--求无向图的割点和桥

    一.基本概念 1.桥:是存在于无向图中的这样的一条边,如果去掉这一条边,那么整张无向图会分为两部分,这样的一条边称为桥无向连通图中,如果删除某边后,图变成不连通,则称该边为桥. 2.割点:无向连通图中 ...

  6. SPF Tarjan算法求无向图割点(关节点)入门题

    SPF 题目抽象,给出一个连通图的一些边,求关节点.以及每个关节点分出的连通分量的个数 邻接矩阵只要16ms,而邻接表却要32ms,  花费了大量的时间在加边上. //   time  16ms 1 ...

  7. tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)

    基本概念 给定无向连通图G = (V, E)割点:对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点割边(桥)若对于e∈E,从图中删去边e之后,G分 ...

  8. Tarjan算法求割点

    (声明:以下图片来源于网络) Tarjan算法求出割点个数 首先来了解什么是连通图 在图论中,连通图基于连通的概念.在一个无向图 G 中,若从顶点i到顶点j有路径相连(当然从j到i也一定有路径),则称 ...

  9. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)

    Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...

随机推荐

  1. git的使用学习(二)git的操作使用

    1.创建版本库 什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改.删除,Git都能跟踪,以便任何时刻都 ...

  2. 安装本地 jar 文件

    Maven 提供了 maven-install-plugin 可将 jar 文件安装至本地 repository.安装命令如下: mvn install:install-file -Dfile= -D ...

  3. C++大数运算模板

    #include<iostream> #include<cstring> #include<cstdio> #include<iomanip> #inc ...

  4. R去掉含有NA的行

    只要数据框中含有NA的行都去掉 final[complete.cases(final),] na.omit(final) 过滤某几列 final[complete.cases(final[,5:6]) ...

  5. linux tar包追加问题

    只能已归档的文件才能追加文件. 如果tar.gz文件是如此生成:#tar -zcvf test.tar.gz  a.txt即tar.gz是压缩(-z)和归档(-c)文件,则无法给它追加文件:若果tar ...

  6. python 之 数据库(创建表的完整语法、基本数据类型)

    10.4 创建表的完整语法 create table 表名( 字段名1 类型[(宽度) 约束条件], 字段名2 类型[(宽度) 约束条件], 字段名3 类型[(宽度) 约束条件] ); #类型:使用限 ...

  7. 嵌入式Linux学习笔记之第二阶段---文件I/O

    1.文件IO的四个函数 一些术语: 不带缓冲的I/O: 每个read和write都调用内核中的一个系统调用. 文件描述符: 一个非负整数,对内核而言,所以打开的文件都通过文件描述符引用. ①打开或创建 ...

  8. Spring AOP日志实现(三)--获取访问者用户名

    通过Security获取访问者用户名: 也可以通过session来获取: 整体思路:

  9. Gitlab服务不能启动postgresql

    源博文:http://www.zxmseed.com/blog/911081 1.查看启动的服务 -sh-4.1$ gitlab-ctl status warning: gitlab-workhors ...

  10. Error while launching application Error: spawn ENOMEM 解决

    当NodeJs PM2 无法启动应用 出现 Error while launching application Error: spawn ENOMEM 错误时     执行一下  pm2 update ...