题目链接

题意 : N个点M条边,允许有重边,让你求出割边的数目以及每条割边的编号(编号是输入顺序从1到M)。

思路 :tarjan求割边,对于除重边以为中生成树的边(u,v),若满足dfn[u] < low[v],则边(u,v)是割边。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; struct node
{
int u ;
int v;
int next ;
int num ;
}p[];
int dfn[],low[] ;//dfn深度优先遍历生成树的顺序,low表示该节点能够到达的祖先的最小编号
int bridge[] ,nbrid,vis[];//桥的编号,割边的条数,vis表示该点是否访问过
int cnt,head[],tot ; void Init()
{
cnt = nbrid = tot= ;
memset(head,-,sizeof(head)) ;
memset(vis,,sizeof(vis)) ;
}
void addedge(int u,int v,int id)
{
//p[cnt].u = u ;
p[cnt].v = v ;
p[cnt].num = id ;
p[cnt].next = head[u] ;
head[u] = cnt ++ ;
//p[cnt].u = v ;
p[cnt].v = u ;
p[cnt].num = id ;
p[cnt].next = head[v] ;
head[v] = cnt ++ ;
} void DFS(int u,int fu)
{
dfn[u] = low[u] = tot++ ;
vis[u] = ;
for(int i = head[u] ; i != - ; i = p[i].next)
{
int v = p[i].v;
if(p[i].num != fu && vis[v] )
{
low[u] = min(low[u],dfn[v]) ;
}
else if( !vis[v] )
{
DFS(v,p[i].num) ;
low[u] = min(low[u],low[v]) ;
if(low[v] > dfn[u])
{
bridge[++nbrid] = p[i].num;
}
}
}
}
int main()
{
int T ,N,M,u,v;
scanf("%d",&T) ;
while(T--)
{
Init() ;
scanf("%d %d",&N,&M) ;
for(int i = ; i <= M ; i++)
{
scanf("%d %d",&u,&v) ;
addedge(u,v,i) ;
}
DFS(,-) ;
sort(bridge+,bridge++nbrid) ;
printf("%d\n",nbrid) ;
for(int i = ; i <= nbrid ; i++)
{
if(i != nbrid)
printf("%d ",bridge[i]) ;
else printf("%d\n",bridge[i]) ;
}
if(T)puts("") ;
}
return ;
}

鹏哥说我那样写的太丑了,非给我改成下边的样子

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; struct node
{
int u ;
int v;
int next ;
int num ;
}p[];
int dfn[],low[] ;
int bridge[] ,nbrid,vis[];
int cnt,head[],tot ;
int fb[];
void Init()
{
cnt = nbrid = tot= ;
memset(head,-,sizeof(head)) ;
memset(vis,,sizeof(vis)) ;
memset(fb,,sizeof(fb));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
}
void addedge(int u,int v,int id)
{
//p[cnt].u = u ;
p[cnt].v = v ;
p[cnt].num = id ;
p[cnt].next = head[u] ;
head[u] = cnt ++ ;
//p[cnt].u = v ;
p[cnt].v = u ;
p[cnt].num = id ;
p[cnt].next = head[v] ;
head[v] = cnt ++ ;
}
void DFS(int u)
{
dfn[u] = low[u] = ++tot;
//vis[u] = 1 ;
for(int i = head[u] ; i != - ; i = p[i].next)
{
int v=p[i].v;
if(fb[i^])continue;
fb[i]=;
if(dfn[v] )//如果该点没被访问过dfn自然为0,所以不用vis数组也可
{
low[u] = min(low[u],dfn[v]) ;
}
else
{
DFS(v) ;
low[u] = min(low[u],low[v]) ;
if(low[v] > dfn[u])
{
bridge[++nbrid] = p[i].num;
}
}
}
}
int main()
{
int T ,N,M,u,v;
scanf("%d",&T) ;
while(T--)
{
Init() ;
scanf("%d %d",&N,&M) ;
for(int i = ; i <= M ; i++)
{
scanf("%d %d",&u,&v) ;
addedge(u,v,i) ;
}
DFS() ;
sort(bridge+,bridge++nbrid) ;
printf("%d\n",nbrid) ;
for(int i = ; i <= nbrid ; i++)
{
if(i != nbrid)
printf("%d ",bridge[i]) ;
else printf("%d\n",bridge[i]) ;
}
if(T)puts("") ;
}
return ;
}

ZOJ 2588 Burning Bridges (tarjan求割边)的更多相关文章

  1. ZOJ 2588 Burning Bridges(求含重边的无向连通图的割边) - from lanshui_Yang

    Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little country ...

  2. ZOJ 2588 Burning Bridges(求桥的数量,邻接表)

    题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2588 Burning Bridges Time Limit: 5 ...

  3. zoj——2588 Burning Bridges

    Burning Bridges Time Limit: 5 Seconds      Memory Limit: 32768 KB Ferry Kingdom is a nice little cou ...

  4. ZOJ Problem - 2588 Burning Bridges tarjan算法求割边

    题意:求无向图的割边. 思路:tarjan算法求割边,访问到一个点,如果这个点的low值比它的dfn值大,它就是割边,直接ans++(之所以可以直接ans++,是因为他与割点不同,每条边只访问了一遍) ...

  5. ZOJ 2588 Burning Bridges(无向连通图求割边)

    题目地址:ZOJ 2588 由于数组开小了而TLE了..这题就是一个求无向连通图最小割边.仅仅要推断dfn[u]是否<low[v],由于low指的当前所能回到的祖先的最小标号,增加low[v]大 ...

  6. zoj 2588 Burning Bridges【双连通分量求桥输出桥的编号】

    Burning Bridges Time Limit: 5 Seconds      Memory Limit: 32768 KB Ferry Kingdom is a nice little cou ...

  7. 【求无向图的桥,有重边】ZOJ - 2588 Burning Bridges

    模板题——求割点与桥 题意,要使一个无向图不连通,输出必定要删掉的边的数量及其编号.求桥的裸题,可拿来练手. 套模板的时候注意本题两节点之间可能有多条边,而模板是不判重边的,所以直接套模板的话,会将重 ...

  8. zoj 2588 Burning Bridges

    题目描述:Ferry王国是一个漂亮的岛国,一共有N个岛国.M座桥,通过这些桥可以从每个小岛都能到达任何一个小岛.很不幸的是,最近Ferry王国被Jordan征服了.Jordan决定烧毁所有的桥.这是个 ...

  9. ZOJ 2588 Burning Bridges 割边(处理重边)

    <题目链接> 题目大意: 给定一个无向图,让你尽可能的删边,但是删边之后,仍然需要保证图的连通性,输出那些不能被删除的边. 解题分析: 就是无向图求桥的题目,主要是提高一下处理重边的姿势. ...

随机推荐

  1. Convert Geometry data into a Geography data in MS SQL Server

    DECLARE @geog GEOGRAPHY; DECLARE @geom GEOMETRY; ); SET @geom = @geom.MakeValid() --Force to valid g ...

  2. iOS学习之UIControl

    一.UIControl初识      1.UIControl是有控制功能的视图(比如UIButton.UISlider.UISegmentedControl等)的父类. 只要跟控制有关的控件都是继承于 ...

  3. java implement

    接口不能被实例化,但是可以声明一个接口类型的变量. eg. A implements B,则可以有B variableName = new A(),这和extends的用法是类似的 接口可被认为是纯抽 ...

  4. UIAlertView(已经过时) UIActionView swift

    // // ViewController.swift // UILabelTest // // Created by mac on 15/6/23. // Copyright (c) 2015年 fa ...

  5. html表格属性

    一.在表格中插入文字及图片 1.把图片及文字分开到不同的[tr]标签表格内. <html> <body> <table border="1" widt ...

  6. 微软职位内部推荐-Senior Software Engineer

    微软近期Open的职位: Are you looking for a big challenge? Do you know why Big Data is the next frontier for ...

  7. java卡与native卡的区别

      JavaCard Native 功能特性 开发语言 l  纯面向对象的Java语言的子集. Java语言先进灵活,开发调试速度快,实现灵活. l  Java没有指针,并且有内部安全机制可以有效的避 ...

  8. 团队项目的NABC

    我们团队项目是做一个基于PC端的截屏软件,我觉得一个好的截屏软件需要具备磁性吸附的功能.当你需要对某个图像或者是其他的什么截屏的时候,精度比较高,不需要那些边框外的东西,磁性吸附就是在你选中的时候尽管 ...

  9. 课堂练习:给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数。

    题目 1 给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数. 2 要求: (1) 写一个函数 f(N) ,返回1 到 N 之间出现的“1”的个数.例如 f(12)  ...

  10. 项目结队开发---NABC分析(成员)

    一.简介 项目名称:校园导航 特点:手机app,简便易用,适合对铁大地形不了解.路痴者使用. 二.NABC分析 N(need):对于新生报到,学生家长参观校园等想要了解校园路线者,本app软件将带给你 ...