题目链接

题意 : 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. JVM学习总结五——性能监控及故障处理工具

    之前扯了四篇理论,这一篇终于可以动动手了.本篇我们将介绍JVM常用的一些工具,这些工具将是我们监控JVM状态.处理故障和调优分析的利器. 不过在开始之前,我还是要先车扯两句:工具终归只是帮助我们我们处 ...

  2. MVC4.0 如何设置默认静态首页index.shtml

    1.不启用二级域名情况下(www.xxx.com)下设置默认静态首页index.shtml 通过配置IIS的默认文档,设置默认首页地址 然后在MVC的路由中写入忽略默认路由代码 routes.Igno ...

  3. MongoDB学习笔记-创建、更新、删除文档

    创建     MongoDB中使用insert方法来向集合插入文档,然后保存到MongoDB中.     db.foo.insert({"hehe":"呵呵"} ...

  4. Datawarehouse

  5. < java.lang >-- StringBuffer字符串缓冲区

    构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符. 特点: 1:可以对字符串内容进行修改. 2:是一个容器. 3:是可变长度的. 4:缓冲区中可以存储任意类型的数据. 5:最终需要变成字符 ...

  6. ORA-12154:TNS:无法解析指定的连接标识符

    ORA-12154:TNS:无法解析指定的连接标识符 1问题的描述 Oracle11g server 64bit服务器端安装在Windows Server2008 Enterprise上,安装Orac ...

  7. Android -- NDK开发入门

    第一步,建立一个普通的Android项目HelloNDK,然后在与src同一级的目录下新建一个jni目录: 第二步,在jni目录下新建一个hello_ndk.c文件,代码如下: #include &l ...

  8. Hibernate 检索查询的几种方式(HQL,QBC,本地SQL,集成Spring等)

    1.非集成Spring hibernate的检索方式,主要有以下五种. 1.导航对象图检索方式.(根据已经加载的对象,导航到其他对象.) 2.OID检索方式.(按照对象的OID来检索对象.) 3.HQ ...

  9. 华为p7怎么打开usb调试模式

    在应用程序列表中选择[设置]进入系统设置菜单,点击[关于手机]  2.在"版本号"上面连续点击七次:  3.现在返回"设置"界面,发现多了一个"开 ...

  10. 搭建SpringMVC+MyBatis开发框架三

    新增spingmvc.xml配置 在WEB-INF下新增spingmvc.xml,主要是配置spring扫描的包:  <?xml version="1.0" encodin ...