图的割点 / 图的割边(桥) 模板

版权声明:记笔记~~~ https://blog.csdn.net/weixin_42765557/article/details/87522469

原文来自我唯一能看得懂的算法书 ——《啊哈!算法》

图的割点

#include <iostream>
#include <algorithm>
int MAXN_Point,MAXN_Edge,root;
bool e[MAXN_Point][MAXN_Point];  // 为true表示两点之间有边
bool flag[MAXN_Point];
int num[MAXN_Point],low[MAX_Point],index; //index 用来进行时间戳的递增
// 割点算法的核心
void dfs(int cur,int f)
{
    int child = 0;
    index++;    //时间戳+1       全局变量默认为0
    num[cur] = index;   //当前顶点cur的时间戳
    low[cur] = index;   //当前顶点cur能够访问到最早的时间戳,刚开始是自己
    for(int i=1;i<=MAXN_Point;i++) {
        if(e[cur][i] == 1) {
            //从生成树的角度来说,此时i为cur的儿子
            if(num[i] == 0) {   //如果顶点i 的时间戳为0,说明顶点i还没有被访问过
                // 从生成树角度来说,此时的i为cur的儿子
                child++;
                dfs(i,cur); //继续往下遍历
                //更新当前顶点cur能访问到最早顶点的时间戳
                low[cur] = min(low[cur],low[i]);
                //如果当前顶点不是根节点并且满足low[i]>=num[cur],则当前顶点为割点
                if(cur != root && low[i] >= num[cur])
                    flag[i] = true;
                //如果当前顶点是根节点,在生成树中根节点必须要有两个儿子,根节点才能使割点
                if(cur == root && child == 2)
                    flah[cur] = true;
            }
            else if(i != f) //点 i 被访问过且不是cur的父节点,说明是cur的祖先
                low[cur] = min(low[cur],num[i])
        }
    }
    return ;
}
int main()
{
    // 读入数据
    cin >> MAXN_Point >> MAXN_Edge;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            e[i][j]=false;
    int t1,t2;
    for(int i=1;i<=MAXN_Edge;i++) {
        cin >> t1 >> t2;
        e[t1][t2] = true;
        e[t2][t1] = true;
    }

    root = 1;
    dfs(1,root); //从一号顶点开始进行深度优先遍历

    for(int i=1;i<=MAXN_Point;i++) {
        if( flag[i])    // i 是割点
            cout << i << endl;
    }

}

图的割边(桥) 

#include <iostream>
#include <algorithm>
using namespace std;
int MAXN_Point,MAXN_Edge,root;
bool e[MAXN_Point][MAXN_Point];  // 为true表示两点之间有边
bool flag[MAXN_Point];
int num[MAXN_Point],low[MAX_Point],index; //index 用来进行时间戳的递增
void dfs(int cur,int f)
{
    index++;
    num[cur] = index;
    low[cur] = index;
    for(int i=1;i<=n;i++) {
        if(e[cur][i] == true) {
            if(num[i] == 0) {
                dfs(i,cur);
                low[cur] = min(low[i],low[cur]);
                if(low[i] > num[cur])
                    cout << cur << "-" << i << endl;    //割边
            }
            else if(i != f)
                low[cur] = min(low[cur],num[i]);
        }
    }
    return ;
}
int main()
{
    // 读入数据
    cin >> MAXN_Point >> MAXN_Edge;
    for(int i=1;i<=MAXN_Point;i++)
        for(int i=1;i<=MAXN_Point;i++)
            e[i][j] = false;
    int t1,t2;
    for(int i=1;i<=MAXN_Point;i++) {
        cin >> t1 >> t2;
        e[t1][t2] = true;
        e[t2][t1] = true;
    }

    root=1;
    dfs(1,root);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42765557/article/details/87522469
今日推荐