题目:
有这么一个无向图,如下:
请找出这个图中的关键节点。
关键节点的意思就是:如果去掉某一个点,剩余其它所有的点都不能连接在一起,则该节点就成为关键节点。
如去掉节点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;
}