割边不需要讨论当前点是否是根节点的情况,因为是不是根节点对结果都无影响。只需要将割点代码中的low[node[x]]>=low[cur]改为low[node[x]]>low[cur]即可,因为如果有等号,node[x]还是可以通过非树边到达cur,此边就不是割边。
割边判断的是node[x]是否可以通过非树边到达cur(cur并不删去),而割点判断的是是否可以通过非树边到达cur之前的点(cur会被删去)。
P.S.这是一个无向图。
输入数据:
6 6
1 4 1 3 4 2 3 2 2 5 5 6
输出(输出割边):
5-6
2-5
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,cnt,node[50],root[50],next[50]; //割边不需要froot变量,因为是不是根节点对结果都无影响
int num[50],low[50],index;
void insert(int u, int v) {
cnt++;
node[cnt] = v;
next[cnt] = root[u];
root[u] = cnt;
}
void biuld() {
for (int i=1; i<=m; i++) {
int u,v;
cin >> u >> v;
insert(u,v);
insert(v,u);
}
}
void bridge(int cur, int father)
{
num[cur] = low[cur] = ++index;
for (int x=root[cur]; x!=-1; x=next[x]) {
if (!num[node[x]]) {
bridge(node[x],cur);
low[cur] = min(low[cur],low[node[x]]);
if (low[node[x]] > num[cur]) //即node[x]不能通过非树边回到cur,node[x]回到 cur只有一条道路,所以这条道路就是割边。
printf("%d-%d\n",cur,node[x]);
}
else if (node[x] != father)
low[cur] = min(low[cur], num[node[x]]);
}
}
int main()
{
cin >> n >> m;
for (int i=1; i<=max(m,n); i++) root[i] = next[i] = -1;
biuld();
bridge(1,-1);
return 0;
}
当然,判断一条边是否为割边的条件也可以写作
if (low[node[x]] == num[node[x]])
printf("%d-%d\n",cur,node[x]);