题目链接:
题目大意:
求出割边的数目和编号
题目分析:
模板题,注意对重边的处理即可
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#define N 10007
#define M 100007
using namespace std;
struct Edge
{
int v,next,id,tag;
}e[M<<2];
int cc,head[N];
void add ( int u , int v , int id )
{
int i;
for ( i = head[u] ; ~i ; i = e[i].next )
if ( e[i].v == v ) break;
if ( ~i )
{
e[i].tag = 1;
e[i].tag = 1;
return;
}
e[cc].v = v;
e[cc].next = head[u];
e[cc].id = id;
e[cc].tag = 0;
head[u] = cc++;
}
vector<int> ans;
int dfn[N],low[N],times;
void tarjan ( int u , int p )
{
dfn[u] = low[u] = ++times;
for ( int i = head[u] ; ~i ; i = e[i].next )
{
int v = e[i].v;
if ( !dfn[v] )
{
tarjan(v,u);
low[u] = min ( low[u] , low[v] );
if ( low[v] > dfn[u] && !e[i].tag )
ans.push_back ( e[i].id );
}
else if ( v != p )
low[u] = min ( low[u] , dfn[v] );
}
}
int t,n,m,u,v;
int main ()
{
scanf ( "%d" , &t );
while ( t-- )
{
ans.clear();
cc = times = 0;
memset ( head , -1, sizeof(head));
memset ( dfn , 0 , sizeof ( dfn ));
scanf ( "%d%d" , &n , &m );
for ( int i = 1 ; i <= m ; i++ )
{
scanf ( "%d%d" , &u , &v );
add ( u , v , i );
add ( v , u , i );
}
for ( int i = 1 ; i <= n ; i++ )
if ( !dfn[i] )
tarjan(i,-1);
printf ( "%d\n" , ans.size());
if ( ans.size())
{
sort ( ans.begin() , ans.end());
printf ( "%d" , ans[0] );
for ( int i = 1 ; i < ans.size() ; i++ )
printf ( " %d" , ans[i] );
puts("");
}
if (t) puts("");
}
}