从这个题目中,我们清楚这是寻找边与边的关系,但是这并不是树,因此我们无法通过构建树来完成题目,对于联通块问题,如果bfs不方便为图标记,那么我们可以通过并查集来寻找联通块,先寻找起始节点与目标结点是否连通(在同一组内),如果不在一组内先输出-1,如果在一组内,就在此基础上再进行逐个删除其他结点的并查集,如果删除某个节点后不能再连通,就ans++
上代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1010;
int x[N], y[N];//存储数据
int n, m;
int p[N];
int st, en;
int find(int x)//查找父节点
{
if(x != p[x]) return find(p[x]);//如果x父节点不等于他本身,那就递归继续寻找父节点
return p[x];
}
bool check(int u)
{
for(int i = 1; i <= n; i++){
p[i] = i;
}
for(int i = 1; i <= m; i++){
if(x[i] == u || y[i] == u) continue;//如果遇到u结点就直接跳过
int px = find(x[i]), py = find(y[i]);
if(px != py) p[px] = py;
}
return find(st) != find(en);
}
int main(void)
{
cin >> n >> m;
for(int i = 0; i <= n; i++) p[i] = i;
for(int i = 1; i <= m; i++){
cin >> x[i] >> y[i];
int px = find(x[i]), py = find(y[i]);//寻找x[i]与y[i]的父节点
if(px != py) p[px] = py;//如果x[i]与y[i]的父节点不同,就让x的父节点等于y的父节点
}
cin >> st >> en;//输入起始节点和目标节点
if(find(st) != find(en)){
cout << -1 << endl;
return 0;
}//如果起始节点和目标节点的父节点不同,说明他们不联通,因此输出-1
int ans = 0;
for(int i = 1; i <= n; i++){//枚举所有点,并检查这个点是不是关键点
if(i != st && i != en){
if(check(i)) ans++;//如果删除该点无法连通,那就是关键点
}
}
cout << ans << endl;
return 0;
}