//Tarjan 割边 //当dfn[u]<low[v]时u与v之间的边为割边 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; int n,m,cnt,ans,head[10001]; int dot,dfn[10001],low[10001]; int cut[200001]; struct uio{ int from,to,next,id; }edge[200001]; void add(int x,int y) { edge[++cnt].next=head[x]; edge[cnt].from=x; edge[cnt].to=y; edge[cnt].id=cnt; head[x]=cnt; } void tarjan(int x,int fa) { dfn[x]=low[x]=++dot; for(int i=head[x];i;i=edge[i].next) { int y=edge[i].to; if(!dfn[y]) { tarjan(y,x); low[x]=min(low[x],low[y]); if(low[y]>dfn[x]) cut[edge[i].id]=1; } else if(y!=fa) low[x]=min(low[x],dfn[y]); } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,i); for(int i=1;i<=cnt;i++) if(cut[i]) ans++; printf("%d\n",ans); for(int i=1;i<=cnt;i++) if(cut[i]) printf("%d %d\n",edge[i].from,edge[i].to); return 0; }
原文:https://www.cnblogs.com/water-radish/p/9280524.html