题目:哈密顿通路是指,在一个无向图中,存在一条经过图中每一个点,且仅经过一次的通路,若这条通路形成了闭合回路,则称这条回路为哈密顿回路,存在哈密顿回路的图称为哈密顿图。现给出无向图G的边,要求判断无向图G中是否存在哈密顿通路,且判断其是否为哈密顿图。
Input:
第一行为节点数n
第二行到倒数第二行为每一条边的信息,每行有两个数字,以空格分开,代表节点编号
最后一行为1-n以外的两个数字,表示输入结束
Output:
“存在哈密顿通路”或“不存在哈密顿通路”,换行
“是哈密顿图”或“不是哈密顿图”
输入样例1:
5
1 2
2 3
3 4
4 5
5 1
0 0
输出样例1:
存在哈密顿通路
是哈密顿图
输入样例2:
5
1 2
1 3
2 3
2 4
2 5
3 4
3 5
0 0
输出样例2:
存在哈密顿通路
不是哈密顿图
解题分析:
先使用一个二维数组存储无向图G的关系矩阵,然后使用广度优先搜索算法,使用变量t存储已经经过的节点。对于每一个节点,若存在未经过的与其关联的节点,则移动到此节点再次搜索,如不存在此节点,则返回。
在每一个节点处进行判断,若t=n,则已经无重复地通过了全部节点,即存在哈密顿通路,在此基础上,若t=n时,所处的点与1号点关联,则形成了哈密顿回路,即为哈密顿图。
实现代码:
#include
#include
using namespace std;
int n,t=0,access=0,circuit=0;
//n为节点数,t为经过节点数,access表示是否为哈密顿通路,circuit表示是否为哈密顿图
int rel[100][100]={0};
int visited[100];
//rel表示无向图G, visited表示经过的节点编号
bool judge(int num){
//judge函数判断num号节点是否存在未经过的关联节点
for(int i=1;i<=n;i++){
if(rel[num][i]==1&&visited[i]==0) return true;
}
return false;
}
void search(int start){
//search函数进行递归,搜索连通图中每一个节点
int i;
t++;
if(t==n) access=1;
//判断哈密顿通路
if(t==n&&rel[start][1]==1) circuit=1;
//判断哈密顿回路
if(!judge(start)) return;
//不存在未经过的关联节点时结束递归
for(i=1;i<=n;i++){
if(rel[start][i]==1&&visited[i]==0){
visited[i]=1;
search(i);
//存在未经过关联节点时继续递归
visited[i]=0;
t--;
//重置经过节点编号与经过节点数
}
}
}
int main() {
cin>>n;
memset(visited,0,sizeof(visited));
//将数组初始化置为未经过
int a,b;
//a,b表示每一条边的两端节点编号
while(1){
//读入无向图G关系矩阵
cin>>a>>b;
if(a>0&&b>0&&a<=n&&b<=n){
rel[a][b]=1;
rel[b][a]=1;
}
else break;
}
visited[1]=1;
//从1号节点开始搜索
search(1);
if(access==1) cout<<"存在哈密顿通路"< //输出结果 else cout<<"不存在哈密顿通路"< if(circuit==1) cout<<"是哈密顿图"< else cout<<"不是哈密顿图"< return 0; }