这道题说白了就是一道点双联通分量的板子题
权当练习
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define RG register
using namespace std;
int nxt[200005],to[200005],head[100005],shu1,shu2,n,m,tot;
int dfn[100005],low[100005],stk[100005],instk[100005];
int ans[100005],pd[100005];
int id[200005],dfs_num,top,cnt,inv[100005];
vector <int> point[100005];
inline int minn(int x,int y)
{
if(x<y) return x;
return y;
}
inline int read()
{
int ans=0,t=1;
char x=getchar();
while(x<'0'||x>'9')
{
if(x=='-') t=-1;
x=getchar();
}
while(x>='0'&&x<='9')
{
ans=ans*10+x-'0';
x=getchar();
}
return ans*t;
}
inline void add(int x,int y,int z)
{
to[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
id[tot]=z;
}
void tarjan(int x,int fa)
{
dfn[x]=low[x]=++dfs_num;
for(RG int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(y==fa) continue;
if(!dfn[y])
{
stk[++top]=y;
tarjan(y,x);
low[x]=minn(low[x],low[y]);
if(low[y]>=dfn[x])
{
cnt++;
while(233)
{
int now=stk[top--];
point[cnt].push_back(now);
if(now==y) break;
}
point[cnt].push_back(x);
}
}
else
{
low[x]=minn(dfn[y],low[x]);
}
}
}
int main()
{
freopen("find.in","r",stdin);
freopen("find.out","w",stdout);
cin>>n>>m;
for(RG int i=1;i<=m;i++)
{
shu1=read();
shu2=read();
add(shu1,shu2,i);
add(shu2,shu1,i);
}
for(RG int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i,i);
for(RG int l=1;l<=cnt;l++)
{
for(RG int j=0;j<point[l].size();j++)
inv[point[l][j]]=1;
for(RG int k=0;k<point[l].size();k++)
{
RG int i=point[l][k];
for(RG int j=head[i];j;j=nxt[j])
{
RG int y=to[j];
if(inv[y])
{
ans[l]++;
}
}
}
for(RG int j=0;j<point[l].size();j++)
inv[point[l][j]]=0;
}
for(RG int l=1;l<=cnt;l++)
{
for(RG int j=0;j<point[l].size();j++)
inv[point[l][j]]=1;
for(RG int k=0;k<point[l].size();k++)
{
RG int i=point[l][k];
for(RG int j=head[i];j;j=nxt[j])
{
RG int y=to[j];
if(inv[y])
{
if(ans[l]==(((int)point[l].size())<<1))
pd[id[j]]=1;
}
}
}
for(RG int j=0;j<point[l].size();j++)
inv[point[l][j]]=0;
}
RG int all=0;
for(RG int i=1;i<=m;i++)
if(pd[i])
all++;
printf("%d\n",all);
for(RG int i=1;i<=m;i++)
if(pd[i])
printf("%d ",i);
return 0;
}