①割点u,当且仅当满足(1)或(2)
(1) u为树根,且u有多于一个子树。
(2) u不为树根,且满足存在(u,v)为树枝边(或称父子边,即u为v在搜索树中的父亲),使得visit[u]<=goback[v]。
②桥无向边(u,v),当且仅当(u,v)为树枝边,且满足visit[u]<goback[v]。
#include <iostream>
int min(int x,int y){
return x>y?y:x;
}
using namespace std;
int duan[1001]; //割点标记
int qiao[1001];
int mark[1001]={0};
int n,m,k;
int visit[1001]={0}; //参观顺序
int goback[1001]={0}; //某点子树可以回溯到的最小点
int p=1;
int parent[1001]={0};
int child[1001]={0}; //记录孩子数量。单纯为了针对根节点
int edge[1001][1001];
void DFS(int x)
{
mark[x]=1;
visit[x]=goback[x]=p;
p++;
for(int i=1;i<=n;i++)
if(edge[x][i]==1)
{
if(mark[i]==0)
{
DFS(i);
parent[i]=x;
goback[x]=min(goback[x],goback[i]);
child[x]++;
if(parent[x]==0&&child[x]>1) duan[x]=1;
if(visit[x]<=goback[i]) duan[x]=1;
if(visit[x]<goback[i]) qiao[x]=i; //(x,i)为桥
}
else
{
if(i!=parent[x])
goback[x]=min(goback[x],visit[i]);
}
}
}