题目大意
给你一张无向图,让你枚举去掉哪一条边后就可以是A点与B点无法互相到达,输出那条边的起点和终点。
解法
不会并查集的戳这里
首先用循环枚举去掉的边,然后通过并查集把没去掉的边加到一起,然后再次枚举每个顶点的祖先,如果有两个以上的点的祖先是自己的话,说明有两个连通块不可以互相到达,然后起点和终点按大小输出即可。
AC代码
#include<bits/stdc++.h>
using namespace std;
int n,m,s,f[50005];
struct node{
int u,v;
}a[50005];
bool cmp(node a,node b){
if(a.u==b.u) return a.v<b.v;
return a.u<b.u;
}
void init(){
for(int i=1;i<=n;i++){
f[i]=i;
}
}
int find(int x){
if(f[x]==x) return x;
return f[x]=find(f[x]);
}
void join(int x,int y){
int f1=find(x);
int f2=find(y);
if(f1!=f2){
f[f2]=f1;
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>a[i].u>>a[i].v;
}
sort(a+1,a+m+1,cmp);
for(int i=1;i<=m;i++){
init();
s=0;
for(int j=1;j<=m;j++){
if(j!=i){
join(a[j].u,a[j].v);
}
}
for(int j=1;j<=n;j++){
if(find(j)==j) s++;
}
if(s>=2) cout<<min(a[i].u,a[i].v)<<" "<<max(a[i].u,a[i].v)<<endl;
}
}