<题目链接>

题目大意:

给定一个无向图,让你尽可能的删边,但是删边之后,仍然需要保证图的连通性,输出那些不能被删除的边。

解题分析:

就是无向图求桥的题目,主要是提高一下处理重边的姿势。

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define clr(a,b) memset(a,b,sizeof(a))
#define rep(i,s,t) for(int i=s;i<=t;i++)
const int N = 1e4+ , M = 1e5+; struct Edge{ int from,to,id,fp,nxt; }e[M<<]; int n,m,tot,cnt;
int head[N],dfn[N],low[N],cut[M];
vector<int>vec; inline void init(){
cnt=tot=;
vec.clear();
clr(dfn,);clr(head,-);clr(cut,);
}
inline void add(int u,int v,int id){
e[cnt]=(Edge){u,v,id,,head[u]};head[u]=cnt++;
}
inline bool isHash(int u,int v){ //因为添加的是双向边,所以这里直接判断一个方向是否有相同边即可
for(int i=head[u];~i;i=e[i].nxt){
int vv=e[i].to;
if(vv==v){
e[i].fp=;
return false;
}
}return true;
}
void Tarjan(int u,int pre){
dfn[u]=low[u]=++tot;
for(int i=head[u];~i;i=e[i].nxt){
int v=e[i].to;
if(v==pre)continue;
if(!dfn[v]){
Tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]&&!e[i].fp){
vec.pb(e[i].id); //存下符合条件的割边
}
}else low[u]=min(low[u],dfn[v]);
}
}
inline void Solve(){
printf("%d\n",vec.size());
sort(vec.begin(),vec.end());
for(int i=;i<vec.size();i++){
if(i!=)printf(" ");
printf("%d",vec[i]);
}
if(vec.size())puts("");
}
int main(){
int T;cin>>T;
while(T--){
read(n);read(m);
init();
rep(i,,m){
int u,v;scanf("%d%d",&u,&v);
if(isHash(u,v)){ //判断重边
add(u,v,i);add(v,u,i);
}
}
Tarjan(,-);
Solve();
if(T)puts("");
}
}
05-07 15:45