For an undirected graph, remove some edges so that the graph is still connected and the edges cannot be removed. Question Analysis: it is to find a bridge without a directed graph. The tarjan algorithm runs once and is very similar to an undirected graph cut point. Here we need to find the edge (u, v) of low [v]> dfn [u) as the cut edge, because v is a child of u, but v cannot access the ancestor of u, It is a bridge to disconnect the source image of this edge. This question has parallel edges, and the parallel edges must not be bridges. Therefore, you need to determine when using dfs. For details, see the code:
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 10005; const int M = 500005; int m,n,num,ansnum,dfns; int head[N],ans[M],low[N],dfn[N]; bool vis[N]; struct node { int to,next,id; }bridge[M<<1]; void build(int s,int e,int id) { bridge[num].id = id; bridge[num].to = e; bridge[num].next = head[s]; head[s] = num ++; } void dfs(int cur,int fa) { vis[cur] = true; int chongbian = 0; dfn[cur] = low[cur] = dfns ++; for(int i = head[cur];i != -1;i = bridge[i].next) { if(fa == bridge[i].to) chongbian ++; if(vis[bridge[i].to] == false) { dfs(bridge[i].to,cur); low[cur] = min(low[cur],low[bridge[i].to]); if(low[bridge[i].to] > dfn[cur]) ans[ansnum ++] = bridge[i].id; } else if(fa != bridge[i].to || chongbian > 1) low[cur] = min(low[cur],dfn[bridge[i].to]); } } void tarjan() { int i; dfns = 1; memset(vis,false,sizeof(vis)); memset(dfn,0,sizeof(dfn)); for(i = 1;i <= n;i ++) if(vis[i] == false) dfs(i,-1); printf("%d\n",ansnum); sort(ans,ans + ansnum); for(i = 0;i < ansnum;i ++) printf(i == ansnum - 1?"%d\n":"%d ",ans[i]); } int main() { int t,i; int a,b; scanf("%d",&t); while(t --) { scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); num = ansnum = 0; for(i = 1;i <= m;i ++) { scanf("%d%d",&a,&b); build(a,b,i); build(b,a,i); } tarjan(); if(t) puts(""); } return 0; }