The topic is to output all cutting edges of a graph without a direction. Using the Tarjan algorithm:
Over Dfs, a depth-first spanning tree is constructed, and the edges in the original graph are divided into two types: the edge of the tree (the edge on the spanning tree) and the anti-ancestor Edge (not the edge on the spanning tree).
By the way, the DFS sequence of each node Dfn[u] and each node can be reached along the atavistic edge of it and its son the smallest DFS order Low[u].
An edge (U,V) is a cutting edge when and only if-
Note that when the specific implementation, the side of the non-directional graph has positive and negative edges in the adjacency table, then if one edge is a tree edge, the other side should not be the anti-ancestor side, to ignore.
1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespacestd;5 #defineMAXM 2222226 #defineMAXN 111117 structedge{8 intV,next;9 BOOLtag;Ten }EDGE[MAXM]; One intNE,HEAD[MAXN]; A voidAddedge (intUintv) { -Edge[ne].v=v; Edge[ne].next=head[u]; edge[ne].tag=0; -head[u]=ne++; the } - intdn,dfn[maxn],low[maxn],res[maxm],resn; - voidDfsintu) { -dfn[u]=low[u]=++DN; + for(intI=head[u]; i!=-1; I=Edge[i].next) { - if(Edge[i].tag)Continue; + intv=edge[i].v; A if(Dfn[v]) { atlow[u]=min (low[u],dfn[v]); - Continue; - } -edge[i].tag=edge[i^1].tag=1; - Dfs (v); -low[u]=min (low[u],low[v]); in if(Low[v]>dfn[u]) res[resn++]= (i>>1)+1; - } to } + intMain () { - intt,n,m,a,b; thescanf"%d",&t); * while(t--){ $scanf"%d%d",&n,&m);Panax NotoginsengNe=0; -memset (head,-1,sizeof(head)); the while(m--){ +scanf"%d%d",&a,&b); A Addedge (A, b); Addedge (b,a); the } +resn=dn=0; -memset (DFN,0,sizeof(DFN)); $Dfs1); $printf"%d\n", RESN); -Sort (res,res+resn); - for(intI=0; i<resn; ++i) { the if(i) Putchar (' '); -printf"%d", Res[i]);Wuyi } the if(RESN) Putchar ('\ n'); - if(t) Putchar ('\ n'); Wu } - return 0; About}
ZOJ2588 Burning Bridges (cut edge)