求割边,实际上跟求割点类似,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) { node *ptr = edge[u].next; while(ptr) { int v = ptr -> v; if(!visited[v]) { visited[v] = 1; tmpdfn++; dfn[v] = low[v] = tmpdfn; 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() { low[1] = dfn[1] = 1; tmpdfn = 1; cnt = 0; memset(visited, 0, sizeof(visited)); visited[1] = 1; 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; }