①割点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]); } } }
扫描二维码关注公众号,回复:
162591 查看本文章