ZOJ Problem - 2588 Burning Bridges tarjan算法求割边
题意:求无向图的割边。
思路:tarjan算法求割边,访问到一个点,如果这个点的low值比它的dfn值大,它就是割边,直接ans++(之所以可以直接ans++,是因为他与割点不同,每条边只访问了一遍)。
需要注意的就是此处有多重边,题目中要求输出确定的不能被删除的边,而多重边的保留不是可以确定的,所以多重边都是不可以被保留的,我们可以在邻接表做一个flag的标记,判断他是不是多重边。
注意建图的时候数组应该是m × 2,因为这里是无向边,当心RE!
注意输出的时候编号是必须要拍好序再输出。
还有一个地方需要注意的就是应该选择高效的建图方式,我一开始看见给了5秒,就用邻接矩阵建了图,毕竟他能很好的记录重边,但交上去并不好使。。。又换了vector,结果莫名其妙的程序崩溃,我都开始怀疑人生了,想到zoj一向以严格刁钻出名,干脆换了比较高效的链式前向星,总算是过了,下面是代码:
后来的补充~
这个后来尚尚告诉我判断边是否出现过可以用这种方法:图中最多有N个点,可以用map解决这个问题,把x和y这两个边压缩成一个整数10*N*X + Y,用map记录下这个数是否出现过,就是这条边有没有出现过.这种方法跑了800ms,我的那种方法跑了1000+ms,看来还是遍历的方式太蠢了,建议读者使用建议方式,如果卡时间也不怕了
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 10010
int head[maxn],tot,dfn[maxn],low[maxn],ans_id[maxn*],ans,cnt;
struct EDGE
{
int to,nxt,flag,id;
} edge[maxn*];
void add_edge(int x,int y,int id)
{
bool mark = true;
int pos = ;
for(int i = head[x]; i != -; i = edge[i].nxt)
{
if(edge[i].to == y)
{
mark = false;
pos = i;
break;
}
}
if(!mark)
{
edge[pos].flag = ;
return;
}
edge[cnt].to = y;
edge[cnt].nxt = head[x];
edge[cnt].flag = ;
edge[cnt].id = id;
head[x] = cnt++;
}
void tarjan(int x,int fa)
{
dfn[x] = low[x] = ++tot;
for(int i = head[x]; i != -; i = edge[i].nxt)
{
int y = edge[i].to;
if(!dfn[y])
{
tarjan(y,x);
low[x] = min(low[x],low[y]);
if(low[y] > dfn[x] && !edge[i].flag)///判断重边
{
ans_id[ans++] = edge[i].id;
}
}
else if(y != fa)
low[x] = min(low[x],dfn[y]);
}
return;
}
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--)
{
cnt = ,tot = ,ans = ;
memset(head,-,sizeof(head));
scanf("%d%d",&n,&m);
for(int i = ; i <= m; i++)
{
int x,y;
scanf("%d%d",&x,&y);
add_edge(x,y,i);
add_edge(y,x,i);
}
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
tarjan(,-);
printf("%d\n",ans);
sort(ans_id,ans_id + ans);
if(ans != )
{
for(int i = ; i < ans; i++)
{
i == ? printf("%d",ans_id[i]) : printf(" %d",ans_id[i]);
}
printf("\n");
}
if(t)
puts("");
}
return ;
}
ZOJ Problem - 2588 Burning Bridges tarjan算法求割边的更多相关文章
- ZOJ 2588 Burning Bridges (tarjan求割边)
题目链接 题意 : N个点M条边,允许有重边,让你求出割边的数目以及每条割边的编号(编号是输入顺序从1到M). 思路 :tarjan求割边,对于除重边以为中生成树的边(u,v),若满足dfn[u] & ...
- UVA 796 Critical Links (tarjan算法求割边)
这是在kuangbin的题目里看到的,不得不吐槽一下,题目中居然没给出数据范围,还是我自己猜的-本来是一道挺裸的题,但是我wa了好多次,原因就是这里面有两个坑点,1重边特判,2输出时左边必须比右边小. ...
- ZOJ 2588 Burning Bridges(求桥的数量,邻接表)
题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2588 Burning Bridges Time Limit: 5 ...
- POJ 1986 Distance Queries (Tarjan算法求最近公共祖先)
题目链接 Description Farmer John's cows refused to run in his marathon since he chose a path much too lo ...
- HDU 1269 迷宫城堡 tarjan算法求强连通分量
基础模板题,应用tarjan算法求有向图的强连通分量,tarjan在此处的实现方法为:使用栈储存已经访问过的点,当访问的点离开dfs的时候,判断这个点的low值是否等于它的出生日期dfn值,如果相等, ...
- tarjan算法求LCA
tarjan算法求LCA LCA(Least Common Ancestors)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先. 这里我们使用tarjan算法离线算法解决这个问题. 离线 ...
- [Tarjan系列] Tarjan算法求无向图的双连通分量
这篇介绍如何用Tarjan算法求Double Connected Component,即双连通分量. 双联通分量包括点双连通分量v-DCC和边连通分量e-DCC. 若一张无向连通图不存在割点,则称它为 ...
- Tarjan算法求有向图强连通分量并缩点
// Tarjan算法求有向图强连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> #inc ...
- tarjan算法求无向图的桥、边双连通分量并缩点
// tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...
随机推荐
- 在IE8中如何通过javascripts改变<style />中的内容?
1.createStyleSheet() if(document.createStyleSheet){ var cssStyle=document.createStyleSheet(); //兼容 ...
- amazeui 搜索 动态
<!doctype html> <html class="no-js"> <head> <meta charset="utf-8 ...
- html5标准格式示代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...
- 安装unbuntu系统后改回windows引导的方法
1.安装EasyBCD 2.点BCD部署 3.分区:选c盘 4.点击编写MBR 5.点编辑引导菜单 6.确定win10后们的是有勾 7.点击保存设置
- python 字符转换
我们所看到的“明文字符串”,都是经过编码(比如ASCII.Uncoded.UTF-8.GB-2312等)后呈现在我们面前的. 文本中“3082”想要“所见到所得”到内存中处理,必须decode('he ...
- Python Cookbook - 1 - 数据结构和算法
1 序列解压:通过*来通配 *a, b = somelist, first, *mid, last = somelist, a, *b = somelist 2 使用双向队列: from col ...
- python 字典排序,列表排序详细
在程序中使用字典进行数据信息统计时,由于字典是无序的所以打印字典时内容也是无序的.因此,为了使统计得到的结果更方便查看需要进行排序.Python中字典的排序分为按“键”排序和按“值”排序. 1.按“值 ...
- apt-get 总结2
本文列举了常用的APT命令参数: apt-cache search package 搜索软件包 apt-cache show package 获取包的相关信息,如说明.大小.版本等 sudo apt ...
- hdu_3565_Bi-peak Number(数位DP)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3565 题意:给你一个区间,让你找这个区间内有两个山峰的数的最大和,什么是两个山峰,比如121121 ...
- 【超级干货】手机移动端WEB资源整合:转载
转载于:http://www.w3cfuns.com/notes/24611/fbba9cbd616e795360ea45515494aa53.html meta基础知识 H5页面窗口自动调整到设备宽 ...