ZOJ2588 Burning Bridges(割边模板)
2016-01-23 20:26
267 查看
题目要输出一个无向图的所有割边。用Tarjan算法:
一遍DFS,构造出一颗深度优先生成树,在原无向图中边分成了两种:树边(生成树上的边)和反祖边(非生成树上的边)。
顺便求出每个结点的DFS序dfn[u] 和 每个结点能沿着它和它的儿子的返祖边达到的结点最小的DFS序low[u]。
一条边(u,v)是割边当且仅当——
low[v]>dfn[u]
注意具体实现时,无向图的边在邻接表中有正反两条边,那么如果一条边是树边了,另一条边不应该是反祖边,要忽略。
一遍DFS,构造出一颗深度优先生成树,在原无向图中边分成了两种:树边(生成树上的边)和反祖边(非生成树上的边)。
顺便求出每个结点的DFS序dfn[u] 和 每个结点能沿着它和它的儿子的返祖边达到的结点最小的DFS序low[u]。
一条边(u,v)是割边当且仅当——
low[v]>dfn[u]
注意具体实现时,无向图的边在邻接表中有正反两条边,那么如果一条边是树边了,另一条边不应该是反祖边,要忽略。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXM 222222 #define MAXN 11111 struct Edge{ int v,next; bool tag; }edge[MAXM]; int NE,head[MAXN]; void addEdge(int u,int v){ edge[NE].v=v; edge[NE].next=head[u]; edge[NE].tag=0; head[u]=NE++; } int dn,dfn[MAXN],low[MAXN],res[MAXM],resn; void dfs(int u){ dfn[u]=low[u]=++dn; for(int i=head[u]; i!=-1; i=edge[i].next){ if(edge[i].tag) continue; int v=edge[i].v; if(dfn[v]){ low[u]=min(low[u],dfn[v]); continue; } edge[i].tag=edge[i^1].tag=1; dfs(v); low[u]=min(low[u],low[v]); if(low[v]>dfn[u]) res[resn++]=(i>>1)+1; } } int main(){ int t,n,m,a,b; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); NE=0; memset(head,-1,sizeof(head)); while(m--){ scanf("%d%d",&a,&b); addEdge(a,b); addEdge(b,a); } resn=dn=0; memset(dfn,0,sizeof(dfn)); dfs(1); printf("%d\n",resn); sort(res,res+resn); for(int i=0; i<resn; ++i){ if(i) putchar(' '); printf("%d",res[i]); } if(resn) putchar('\n'); if(t) putchar('\n'); } return 0; }
相关文章推荐
- 【C语言】写一个函数,实现字符串内单词逆序
- PHP 清除 Excel 导入的数据空格
- iOS像素和点的转换
- matlab下 hsi转rgb代码
- 动态规划算法
- 解决PHPExcel导出长数字末尾几位数为0的问题
- poj1990
- Android Studio 使用 lint 优化代码
- 扣丁学堂——双缓存实例(处理较大网络图片)
- DoNet开源项目-基于jQuery EasyUI的后台管理系统
- Unity 5.3配置开发环境、安卓环境
- tomcat配置网站位置
- hdu 3336 Count the string(KMP+dp)
- Android源码剖析之-----Activity的启动过程
- android状态栏一体化(改变状态栏的背景颜色)类似于IOS
- jQuery.on() 函数详解
- I think I Need a Houseboat
- mysql分区查询
- 《穷人的小孩难成功-走出人生负面循环》视野的继承与影
- HDU 2601