求割边,实际上跟求割点类似,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;
}