割点和桥

①割点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]);
            }
        }
 }





猜你喜欢

转载自blog.csdn.net/yxpandjay/article/details/78008883