求割边,实际上跟求割点类似,dfs的过程中就能求出割边,判断条件变为low[v] > dfn[u]和(u,v)不能是重边
我用的邻接表存储,结构体中新增的一个变量,用来判断是否有重边
每次插入边之前先扫描一遍该点的邻接点,看是否已经存在一个边
/*
ID: sdj22251
PROG: subset
LANG: C++
*/
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#define LOCA
#define MAXN 10005
#define INF 100000000
#define eps 1e-7
using namespace std;
struct node
{int v, w, id;node *next;
} edge[MAXN];
int visited[MAXN];
int n, m;
int tmpdfn;
int dfn[MAXN];
int low[MAXN];
int ans[200005];
int cnt;
void dfs(int u, int father)
{visited[u] = 1;tmpdfn++;dfn[u] = low[u] = tmpdfn;node *ptr = edge[u].next;while(ptr){int v = ptr -> v;if(!visited[v]){dfs(v, u);low[u] = min(low[u], low[v]);if(low[v] > dfn[u] && ptr -> w == 0){ans[cnt++] = ptr -> id;}}else if(v != father){low[u] = min(low[u], dfn[v]);}ptr = ptr -> next;}
}
void init()
{tmpdfn = 0;cnt = 0;memset(visited, 0, sizeof(visited));for(int i = 0; i <= n; i++){edge[i].w = 0;edge[i].next = NULL;}
}
void insert(const int &x, const int &y, const int &id)
{node *ptr = edge[x].next;bool flag = false;while(ptr){if(ptr -> v == y){ptr -> w = 1;flag = true;}ptr = ptr -> next;}if(!flag){node *pptr = new node;pptr -> v = y;pptr -> id = id;pptr -> w = 0;pptr -> next = edge[x].next;edge[x].next = pptr;}
}
int main()
{int T, x, y, cas = 0;scanf("%d", &T);while(T--){if(cas++) printf("\n");scanf("%d%d", &n, &m);init();for(int i = 1; i <= m; i++){scanf("%d%d", &x, &y);insert(x, y, i);insert(y, x, i);}dfs(1, 0);printf("%d\n", cnt);sort(ans, ans + cnt);for(int i = 0; i < cnt - 1; i++)printf("%d ", ans[i]);if(cnt) printf("%d\n", ans[cnt - 1]);}return 0;
}