ZOJ2588 Burning Bridges 无向图的割边
题目大意:求无向图的割边编号。
割边定义:在一个连通图中,如果删去一个边e,图便变成不连通的两个部分,则e为该图的割边。
求法:边(u,v) 不是割边,当且仅当边(u,v)在一个环内。因此所有不在环内的边就是割边,我们要找到它。对图进行Dfs,对每个节点盖上时间戳DfsN,Dfs的方式形成了一棵搜索树。不在环内的边一定在搜索树中(证明:假设不在环内边e不在搜索树中,则Dfs时要访问该边的to点就会经过另外一条边e'。Dfs的出发点是相同的,因此必然e,e'在一个环内),我们要找到它。如果边(u,v)(u->DfsN < v->DfsN)在一个环内,则v的子树中必然存在一节点a与u的祖先节点(包括u)用一个子树外的边相连(与a相连的每一条树外边的to点b都是v的祖先。证明:如果不是,在Dfs时,要么在站在v上向下搜索时把b纳为v的子树,要么在站在b上向下搜索时把v纳为v'的子树)。定义满足该条件的祖先节点们中DfsN最小的节点的DfsN值为u->Low,如果u->DfsN < v->Low,则边(u,v)是割边。易得:u->Low=min{u->DfsN, each v∈u的子节点且未被访问{v->Low},each e∈v树外边{e->To->DfsN}}。
特判:选边向下遍历时,如果e==曾经到达u的边的反向边,则跳过。因为两条边实际上是一条边。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int MAX_NODE = 10010, MAX_EDGE = 100010 * 2; struct Node;
struct Edge; struct Node
{
int Id, DfsN, Low;
Edge *Head;
}_nodes[MAX_NODE], *Root;
int _vCount, DfsCnt; struct Edge
{
Node *From, *To;
Edge *Next, *Rev;
bool IsCut;
Edge(){}
Edge(Node *from, Node *to, Edge *next)
:From(from),To(to),Next(next),IsCut(false){}
}*_edges[MAX_EDGE];
int _eCount; void Init(int vCount)
{
Root = 1 + _nodes;
_vCount = vCount;
_eCount = 0;
DfsCnt = 0;
memset(_nodes, 0, sizeof(_nodes));
} Edge *NewEdge()
{
_eCount++;
return _edges[_eCount] ? _edges[_eCount] : _edges[_eCount] = new Edge();
} Edge *AddEdge(Node *from, Node *to)
{
Edge *e = NewEdge();
e->From = from;
e->To = to;
e->Next = from->Head;
e->IsCut = false;
from->Head = e;
return e;
} void Build(int uId, int vId)
{
Node *u = uId + _nodes, *v = vId + _nodes;
u->Id = uId;
v->Id = vId;
Edge *e1 = AddEdge(u, v), *e2 = AddEdge(v, u);
e1->Rev = e2;
e2->Rev = e1;
} void Dfs(Node *u, Edge *prev)
{
u->DfsN = ++DfsCnt;
u->Low = u->DfsN;
for (Edge *e = u->Head; e; e = e->Next)
{
if (!e->To->DfsN)
{
Dfs(e->To, e);
u->Low = min(u->Low, e->To->Low);
if (u->DfsN < e->To->Low)
e->IsCut = e->Rev->IsCut = true;
}
else if (prev && e != prev->Rev)
u->Low = min(u->Low, e->To->DfsN);
}
} int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
int testCase, totNode, totEdge, uId, vId;
scanf("%d", &testCase);
while (testCase--)
{
scanf("%d%d", &totNode, &totEdge);
Init(totNode);
for (int i = 1; i <= totEdge; i++)
{
scanf("%d%d", &uId, &vId);
Build(uId, vId);
}
Dfs(Root, NULL);
int ans[MAX_EDGE / 2 + 1], pAns = 0;
for (int i = 1; i <= _eCount; i+=2)
if (_edges[i]->IsCut)
ans[++pAns] = i;
printf("%d\n", pAns);
for (int i = 1; i < pAns; i++)
printf("%d ", (ans[i]+1)/2);
if(pAns)
printf("%d\n", (ans[pAns] + 1) / 2);
if (testCase)
printf("\n");
}
return 0;
}
ZOJ2588 Burning Bridges 无向图的割边的更多相关文章
- zoj2588 Burning Bridges(无向图的桥)
题目请戳这里 题目大意:给一张无向图,现在要去掉一些边,使图仍然连通,求不能去掉的边. 题目分析:就是求无向图的桥. tarjan算法跑一遍,和无向图割点十分类似,这里要找low[v] > df ...
- ZOJ2588 Burning Bridges(割边模板)
题目要输出一个无向图的所有割边.用Tarjan算法: 一遍DFS,构造出一颗深度优先生成树,在原无向图中边分成了两种:树边(生成树上的边)和反祖边(非生成树上的边). 顺便求出每个结点的DFS序dfn ...
- ZOJ 2588 Burning Bridges (tarjan求割边)
题目链接 题意 : N个点M条边,允许有重边,让你求出割边的数目以及每条割边的编号(编号是输入顺序从1到M). 思路 :tarjan求割边,对于除重边以为中生成树的边(u,v),若满足dfn[u] & ...
- zoj2588 Burning Bridges --- 寻求尖端
#include <iostream> #include <cstring> #include <string> #include <cstdio> # ...
- ZOJ 2588 Burning Bridges(求含重边的无向连通图的割边) - from lanshui_Yang
Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little country ...
- Burning Bridges 求tarjan求割边
Burning Bridges 给出含有n个顶点和m条边的连通无向图,求出所有割边的序号. 1 #include <cstdio> 2 #include <cstring> 3 ...
- ZOJ Problem - 2588 Burning Bridges tarjan算法求割边
题意:求无向图的割边. 思路:tarjan算法求割边,访问到一个点,如果这个点的low值比它的dfn值大,它就是割边,直接ans++(之所以可以直接ans++,是因为他与割点不同,每条边只访问了一遍) ...
- 连通性2 无向图的割边 (cut edge)
这是DFS系列的第二篇 割边的概念 In graph theory, a bridge, isthmus, cut-edge, or cut arc is an edge of a graph who ...
- zoj 2588 Burning Bridges【双连通分量求桥输出桥的编号】
Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little cou ...
随机推荐
- MySQL学习笔记之右连接
MySQL的右连接 #右连接,以右表为基表 select course.stuid,course.stuname,sex,course,city from class1 right join cour ...
- Ajax 传递json字符串到客户端时报 Internal server error
架构:struts2+JQuery 需求:就是前台请求后台,后台查询数据库,将数据转换成json格式,使用struts2框架赋值给action内的变量jsonStr,前台通过 response.jso ...
- href标签中target的几个属性值
没有指定<a>的target属性值时,默认是"_blank,可以参考以下代码的设置来控制<a href="#" target="_blank& ...
- OpenCV:使用 随机森林与GBDT
随机森林顾名思义,是用随机的方式建立一个森林.简单来说,随机森林就是由多棵CART(Classification And Regression Tree)构成的.对于每棵树,它们使用的训练集是从总的训 ...
- 【sqli-labs】 less22 Cookie Injection- Error Based- Double Quotes - string (基于错误的双引号字符型Cookie注入)
注入的过程和less 20 21一样,这次闭合cookie的使用的双引号
- Typeclassopedia
https://wiki.haskell.org/wikiupload/8/85/TMR-Issue13.pdf By Brent Yorgey, byorgey@gmail.com Original ...
- webstorm前端开发工具vue环境配置及运行项目
1:webstorm的安装:2:node.js的安装3:安装Git4:vue-cli 安装前面两步就可以把项目启动了,安装Git主要是打开命令窗口,这样就可以用liunx命令了,原理跟cmd差不多 V ...
- BZOJ 1715: [Usaco2006 Dec]Wormholes 虫洞 DFS版SPFA判负环
Description John在他的农场中闲逛时发现了许多虫洞.虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前).John的每个农场有M条小路(无向边)连接着N ...
- 拷贝构造和拷贝赋值、静态成员(static)、成员指针、操作符重载(day06)
十七 拷贝构造和拷贝赋值 浅拷贝和深拷贝 )如果一个类中包含指针形式的成员变量,缺省的拷贝构造函数只是复制了指针变量的本身,而没有复制指针所指向的内容,这种拷贝方式称为浅拷贝. )浅拷贝将导致不同对象 ...
- SpringBoot快速创建HelloWorld项目
废话不多提,拿起键盘,打开 IDEA 就是一通骚操作. 打开 IDEA 后,首页选择 Create New Project,再接着按下图所示,快速搭建SpringBoot项目. 接下来将 Group ...