题目链接

题意 : 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. poj 1564 Sum It Up

    题目连接 http://poj.org/problem?id=1564 Sum It Up Description Given a specified total t and a list of n ...

  2. hdu 4217 Data Structure?/treap

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4217 可用线段树写,效率要高点. 这道题以前用c语言写的treap水过了.. 现在接触了c++重写一遍 ...

  3. JVM学习总结二——垃圾回收算法

    昨天总结了JVM内存分区相关的知识,这次我们将来了解下JVM的另一个核心知识点——垃圾回收算法.这一部分其实并不太难,如果对操作系统的内存处理算法有所了解,那么这部分算法其实只看名字就能明白,两者在原 ...

  4. extension 的一个应用 - 优化图片的读取机制

    枚举和 extension 都是 swift 中非常好用的特性.这里我们就来讨论一个应用的例子,供大家参考. 我们在开发 app 的时候,都会用到各种图片资源,而我们读取图片资源时主要是通过UIIma ...

  5. Spark 3000门徒第二课scala面向对象总结

    昨晚听了王家林老师3000门徒spark系列课程的第二课,讲述了scala面向对象知识,并且带着过了一遍Spark核心类:SparkContent,RDD的代码,下面写一下心得: RDD是抽象类,实现 ...

  6. 000 VS2013 c++ 框架

    #include <Windows.h> //全局函数声明 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, ...

  7. [DllImport("kernel32.dll")]是什么意思??

    转载自:http://blog.csdn.net/sp6645597/article/details/8683737 1.简单说明 这叫引入kernel32.dll这个动态连接库(顾名思义就是一个链接 ...

  8. P1231: [Usaco2008 Nov]mixup2 混乱的奶牛

    这是一道状压DP,首先这道题让我意识到状态是从 1 to (1<<n)-1 的,所以当前加入的某头牛编号是从 0 to n-1 的,所以存储的时候习惯要改一下,这样子做状压DP才会顺一点吧 ...

  9. java静态变量、静态方法和静态代码段

    先上实例 public class TestStatic { public static String staticString = "this is a static String&quo ...

  10. BICEP单元测试计划-四则运算-测试

    一.6个值得测试的具体部位,他们能够提高你的测试技巧 Right-结果是否正确? B-是否所有的边界条件都是正确的? I-能查一下反向关联吗? C-能用其他手段交叉检查一下结果吗? E-你是否可以强制 ...