割边 发表于 2018-08-12 | 分类于 OI 字数统计: 357 | 阅读时长 ≈ 2 当且仅当,存在,它为桥需要注意的是,当存在重边时,可以用来更新 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364#include<cstdio>#include<cstring>#include<vector>using namespace std;const int N=10050,M=100050;int n,m,num,low[N],dfn[N],cut[M];vector<int> e[N],g[N];inline int read(){ register int x=0,t=1; register char ch=getchar(); while (ch!='-'&&(ch<'0'||ch>'9')) ch=getchar(); if (ch=='-') t=-1,ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar(); return x*t;}void add(int u,int v,int id){ e[u].push_back(v); g[u].push_back(id);}void tarjan(int o,int id){ low[o]=dfn[o]=++num; for(int i=0;i<e[o].size();i++) { int to=e[o][i]; if (!dfn[to]) { tarjan(to,g[o][i]); low[o]=min(low[o],low[to]); if (low[to]>dfn[o]) cut[g[o][i]]=1; } else if (g[o][i]!=id) low[o]=min(low[o],dfn[to]); }}int main(){ int T=read(); while (T--) { n=read(),m=read(),num=0; for(int i=1;i<=n;i++) e[i].clear(); for(int i=1;i<=n;i++) g[i].clear(); memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(cut,0,sizeof(cut)); for(int i=1;i<=m;i++) { int u=read(),v=read(); add(u,v,i),add(v,u,i); } for(int i=1;i<=n;i++) if (!dfn[i]) tarjan(i,0); int ans=0; for(int i=1;i<=m;i++) if (cut[i]) ans++; printf("%d\n",ans); for(int i=1;i<=m;i++) if (cut[i]) printf("%d ",i); } return 0;}