深度搜索的应用----无向图的连通性

题目:

有这么一个无向图,如下:


请找出这个图中的关键节点。

关键节点的意思就是:如果去掉某一个点,剩余其它所有的点都不能连接在一起,则该节点就成为关键节点。

如去掉节点3,如下图:


去掉节点3以后,很明显所有的节点并不能完全连接,那么节点3就是这个无向图中的一个关键节点。


如果去掉节点6,如下图所示:


去掉节点6以后,很明显所有的节点依然可以完全连接,那么节点6就不是该无向图中的关键节点。

要求输入如下:

8       //8代表有8个节点

10    //10代表以下有10组数据,分别表示无向图中节点的连接关系

1 2

1 3

1 5

3 8

3 6

6 8

7 4

2 7

5 7

5 3

要求输入图中所有的关键节点,(如上图很明显可以看出关键节点是3和7)


分析:利用深度搜索的算法,当去掉某一个节点以后,判断剩余的其他节点是否可以全部遍历一次。

用一个一维数组记录每个节点的访问情况:

0----表示目前该节点没有被访问过;

1----表示目前该节点已经被访问过了;

2----表示目前该节点已近被去掉;

关于深度搜索的概念这里就不介绍了,下面给出代码部分和详细的注解


代码部分:

#include <iostream>
 
using namespace std;
 
int visit[100];            //用于记录并判断某一节点的情况
int vertex;                //节点的个数
 
void DFS(int array[100][100], int node)
{
    //判断第i个节点是否被访问过了,如果已经被访问过了就返回,否则标记为被访问过了
    if( 1 == visit[node])
    {
        return;
    }

    visit[node] = 1;
    int i;
    for(i = 0; i < vertex; ++i )
    {
        //当存在连通性,而且该节点没有被访问过,同时该节点不是被删除的节点
        if( 1 == array[node][i] && 2 != visit[i] && 1!= visit[i])
        {
            DFS(array, i);
        }                
    }    
}
 
int main()
{
    
    int road;        //所有的节点一共有几条通路
    int array[100][100];    //本题虽然是8个节点,但是我们稍微加大一点矩阵的边长,以方便测试更多的数据
    
    int edge1[100];        //用于输入无向图中节点与节点连通图的关系
    int edge2[100];
    
    int result[100]= {0,};    //用于记录最后的结果
    int count = 0;
    
    cin >> vertex >> road;
    
    int i,j;
    for( i = 0; i < road; ++i)
    {
        cin >> edge1[i] >> edge2[i];
    }
    //至此,以上所有的输入完成,下面初始化话array数组和visit数组
    //初始化二维数组array和一维数组visit,即开始的时候节点不存在任何关系
    for( i = 0; i < vertex; ++i)
    {
        for(j = 0; j < vertex; ++j)
        {
            array[i][j] = 0;                        
        }
        visit[i] = 0;
    }
    //把节点与节点之间的关系填入到二维数组array中,节点与节点的关系是个对称矩阵,如果存在连通性,就赋值为1
    for( i = 0; i < road; ++i)
    {
        array[edge1[i] -1 ][edge2[i]-1 ] = 1;
        array[edge2[i] -1 ][edge1[i]-1 ] = 1;
    }
    
    //用深度搜索判断某个点是否为关键节点,首先把该节点剔除掉,visit[i]赋值2
    for(i= 0; i < vertex; ++i)
    {
        for(j = 0; j < vertex; ++j)
        {
            //每对任意一个节点做判断时,都初始化visit数组,去掉的节点为2,其它剩余节点都标记为未访问过的节点
            if(i != j)
            {
                visit[j] = 0;
            }
            else
            {
                visit[j] = 2;
            }
        }
        //如果去掉的是头节点,那么取第二个节点作为头节点进行深度遍历,否则都是从头节点进行深度搜索
        if( 0 == i)
        {
            DFS(array, 1);
        }
        else
        {
            DFS(array, 0);
        }
        //深度搜索结束以后,判断第i节点是否为关键节点
        for(j = 0; j < vertex; ++j)
        {
            //如果遍历完visit以后,还存在没访问过的点,就说明该点是关键节点
            if(0 == visit[j])
            {
                result[count++] = i + 1 ;   //该处+1是为了和题目的节点标号统一,程序里实际上从0节点开始进行深度遍历的
                break;
            }
        }
    }
    
    cout << "Key node is : ";
    for(i = 0 ; i < count; ++i)
    {
        cout << result[i] << "  ";
    }
    cout << endl;
    return 0;
}
              


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值