算法学习之 图的割点

原创 2016年08月29日 23:23:52

一.图的割点

先解释一下什么叫图的割点吧,割点就是如果去掉这个点之后无法实现所有点的相互连通,那么这个点就是割点。

二.寻找图的割点

那么给定一张图怎么找到图的割点呢,当然了,所谓割点当然应该是一个图里只有一个强联通分量吧,那么说一下我们大致的算法,我们判断一个节点u是否是割点,就是判读他的子节点中是否存在节点不经过这个节点就无法回到祖先,如果是这样的,那么这个节点就是割点。我们用dfn[u]来记录访问到u的时间戳,low[u]来记录u节点在不经过其父节点所能访问到的最早时间戳(就是第一个能够访问到的祖先节点编号),有了这两个数据,那么根据我们上面的算法我们知道如果low[i]>=num[cur](i是cur的子节点),那么也就是说i没法回到祖先,所以说cur应该是割点

三.数据

n个点m个边,无向图

6 7

1 3

1 4

4 2

3 2

2 5

2 6

5 6

//
//  main.cpp
//  图的割点
//
//  Created by 张嘉韬 on 16/8/29.
//  Copyright © 2016年 张嘉韬. All rights reserved.
//

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=1000;
int min(int a,int b)
{
    if(a<b) return a;
    else return b;
}
int map[maxn][maxn],n,m,x,y,root,flag[maxn],indx,num[maxn],low[maxn];
void dfs(int cur,int father)
{
    int child=0;
    indx++;
    num[cur]=indx;
    low[cur]=indx;
    for(int i=1;i<=n;i++)
    {
        if(map[cur][i]==1)
        {
            if(!num[i])
            {
                dfs(i,cur);// 子节点就去dfs()
                low[cur]=min(low[cur],low[i]);
                if(cur!=root&&low[i]>=num[cur]) flag[cur]=1;
                if(cur==root&&child==2) flag[cur]=1;//虽然未遍历完但是如果有两个两个子节点了那么一定就是割点。
            }
            else if(num[i]&&i!=father)
                low[cur]=min(num[i],low[cur]);
        }
    }
}
int main(int argc, const char * argv[]) {
    freopen("/Users/zhangjiatao/Documents/暑期训练/input.txt","r",stdin);
    memset(map,0,sizeof(map));
    memset(flag,0,sizeof(flag));
    memset(num,0,sizeof(num));
    memset(low,0,sizeof(low));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        map[x][y]=1;
        map[y][x]=1;
    }
    root=1;
    indx=0;
    dfs(1,root);
    for(int i=1;i<=n;i++) cout<<num[i]<<" ";
    cout<<endl;
    for(int i=1;i<=n;i++) cout<<low[i]<<" ";
    cout<<endl;
    for(int i=1;i<=n;i++)
        if(flag[i]) printf("%d\n",i);
    return 0;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

图的割点算法vs图的割边算法

图的割点 在一个无向连通图中,如果删除某个顶点后,图不再连通(即任意两点之间不能相互到达),我们称这样的顶点为割点(或者称割顶)。 上图中的2号顶点就是割点,因为删除2号后,4,5不通,1...

查找图的割点的算法 基本算法

//额外增加sum数组记录最后可以生成的独立的子树的个数 #include"iostream" #include"cstdio" using namespace std; ...

用Tarjan算法求无向连通图割点&&割边

/** 割点割边挺好理解的,割点就是一个无向连通图,把其中一个点 挖掉剩下的图不连通,割边就是把一条边砍掉不连通 比如:有一个通信网络,要求一颗炸弹,把这个通信网络搞得不连通...
  • zcube
  • zcube
  • 2015年09月05日 10:11
  • 2226

tarjan算法--求无向图的割点和桥

一.基本概念     1.桥:是存在于无向图中的这样的一条边,如果去掉这一条边,那么整张无向图会分为两部分,这样的一条边称为桥无向连通图中,如果删除某边后,图变成不连通,则称该边为桥。  ...
  • Ezereal
  • Ezereal
  • 2016年10月11日 22:30
  • 390

基于DFS求无向图的割点及桥(割边)算法总结 POJ_1144题解

1.割点,桥(割边)定义: 若v2(v1的后继节点)有且仅有反向边最远连接到v1,那么删除v1后不连通,v1是割点。作为一种特殊情况,如果v2及其后代通过反向边只能连回v2自己,那么只要删除edge...
  • zl_130
  • zl_130
  • 2015年08月13日 16:43
  • 178

Tarjan算法求无向图割边割点、最近公共祖先的总结

无向图tarjan求割边割点、最近公共祖先总结 割点:删除这个点之后整个图变成不连通的两个部分的点 割点集合:在一个无向图中删除该集合中的所有点,能使原图变成互不相连的连通块的点的集合 点连通度...
  • MrH929
  • MrH929
  • 2016年07月19日 19:49
  • 1125

无向图 点连通tarjan算法 求割点 + 求BCC以及BCC里面的点 + 求去掉每个点后图中BCC数目 【总结】

这两天看 双联通看的难受 .. 还好有点收获题目:给定一个有N个点M条边组成的无向图 1,求出图中BCC数目以及每个BCC里面的点。 2,求出所有割点。 3,求出去掉每个点后图中还剩多少个BCC...

图论——寻找无向连通图割点算法

查看原文:http://www.wyblog.cn/2016/12/20/%e5%9b%be%e8%ae%ba-%e5%af%bb%e6%89%be%e6%97%a0%e7%9b%b8%e8%bf%9...

POJ1523.SPF——无向图的割点,并求连通分支数(tarjan算法)

http://poj.org/problem?id=1523题目描述: 给定一张无向图,求割点,并求删除该割点所得的连通分支数#include #include #include #include ...

无向图 点连通tarjan算法 求割点 + 求BCC以及BCC里面的点 + 求去掉每个点后图中BCC数目 【总结】

看了好久,终于把点——双联通看懂了。 题目:给定一个有N个点M条边组成的无向图,求无向图中的割点以及去掉该点后分成的BCC数目,若不存在割点输出No SPF nodes。 思路: tarjan算...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:算法学习之 图的割点
举报原因:
原因补充:

(最多只允许输入30个字)