【id:697】【15分】E. 汉密尔顿回路

题目描述

著名的“汉密尔顿(Hamilton)回路问题”是要找一个能遍历图中所有顶点的简单回路(即每个顶点只访问 1 次)。本题就要求你判断任一给定的回路是否汉密尔顿回路。

输入

首先第一行给出两个正整数:无向图中顶点数 N(2<N≤200)和边数 M。

随后 M 行,每行给出一条边的两个端点,格式为“顶点1 顶点2”,其中顶点从 1 到N 编号。

再下一行给出一个正整数 K,是待检验的回路的条数。

随后 K 行,每行给出一条待检回路,格式为:n V​1​ V​2​​ ⋯ V​n​​

其中 n 是回路中的顶点数,V​i​​ 是路径上的顶点编号。

输出

对每条待检回路,如果是汉密尔顿回路,就在一行中输出"YES",否则输出"NO"。

输入输出样例

输入样例1 <-复制
6 10
6 2
3 4
1 5
2 5
3 1
4 1
1 6
6 3
1 2
4 5
6
7 5 1 4 3 6 2 5
6 5 1 4 3 6 2
9 6 2 1 6 3 4 5 2 6
4 1 2 5 1
7 6 1 3 4 5 2 6
7 6 1 2 5 4 3 1


输出样例1
YES
NO
NO
NO
YES
NO

AC代码

#include<iostream>
using namespace std;

int n, m;
int juzhen[200][200];
int lu[200];
int dian[200];

void show()
{
	cout << endl;
	int i, j;
	for (i = 1; i <= n; i++)
		for (j = 1; j <= n; j++)
		{
			cout << juzhen[i][j] << " ";
			if (j == n)
				cout << endl;
		}
	cout << endl;
}

int main()
{
	cin >> n >> m;
	int i, j;

	// 初始化邻接矩阵
	for (i = 1; i <= n; i++)
		for (j = 1; j <= n; j++)
			juzhen[i][j] = 0;

	// 读取边的信息并在邻接矩阵中标记有边相连的顶点
	for (i = 1; i <= m; i++)
	{
		int a, b;
		cin >> a >> b;
		juzhen[a][b] = juzhen[b][a] = 1;
	}
	
	//show();

	int k;
	cin >> k;
	while (k--)
	{
		int flag = 1;
		int num;
		cin >> num;
		for (i = 1; i <= num; i++)
			lu[i] = 0;

		for (i = 1; i <= n; i++)
			dian[i] = 0;

		// 读取路径信息
		for (i = 1; i <= num; i++)
			cin >> lu[i];

		// 判断路径是否有效
		if (num != n + 1)
			cout << "NO" << endl;
		else
		{
			for (i = 1; i < num; i++)
			{
				if (dian[i] == 1)
					flag = 0;
				if (juzhen[lu[i]][lu[i + 1]] != 1)
					flag = 0;
				dian[i] == 1;
			}
			if (lu[1] != lu[num])
				flag = 0;
			if (flag == 0)
				cout << "NO" << endl;
			else
				cout << "YES" << endl;
		}

	}
}

该代码实现了路径的判断。首先读取顶点数n和边数m。然后创建一个大小为n的邻接矩阵,并初始化为0。接下来,根据边的信息更新邻接矩阵,标记有边相连的顶点。

然后,读取要判断的路径个数k。对于每个路径,首先判断路径长度是否为n+1,如果不是,则输出"NO"。

否则,遍历路径上的顶点,检查是否存在连续的两个顶点不相邻,或者首尾顶点不同。如果满足这些条件,则输出"YES",否则输出"NO"。

(by 归忆) 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我明白了。下面是一个示例代码,供你参考: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXN 210 int G[MAXN][MAXN]; // 邻接矩阵表示图 int visited[MAXN]; // 记录节点是否被访问过 int path[MAXN]; // 记录路径 int N, M, K; // 图中顶点数、边数、待检回路数 // 判断是否是汉密尔顿回路 int isHamiltonian(int *path, int n) { int i, j; // 判断路径首尾是否相接 if (path[1] != path[n] || n != N + 1) { return 0; } // 判断路径是否经过了所有顶点 memset(visited, 0, sizeof(visited)); visited[path[1]] = 1; for (i = 2; i <= N + 1; i++) { j = path[i]; if (!G[path[i-1]][j] || visited[j]) { return 0; } visited[j] = 1; } return 1; } // DFS汉密尔顿回路 int dfs(int v, int depth) { int i; // 如果已经汉密尔顿回路,直接返回 if (depth == N + 1 && G[v][path[1]]) { return 1; } // DFS遍历 for (i = 1; i <= N; i++) { if (!visited[i] && G[v][i]) { visited[i] = 1; path[depth] = i; if (dfs(i, depth + 1)) { return 1; } visited[i] = 0; } } return 0; } int main() { int i, j, k; int v1, v2; // 读入图 scanf("%d%d", &N, &M); for (i = 0; i < M; i++) { scanf("%d%d", &v1, &v2); G[v1][v2] = G[v2][v1] = 1; // 无向图 } // 汉密尔顿回路 visited[1] = 1; path[1] = 1; dfs(1, 2); // 读入待检回路,判断是否为汉密尔顿回路 scanf("%d", &K); for (k = 0; k < K; k++) { int n; scanf("%d", &n); for (i = 1; i <= n; i++) { scanf("%d", &path[i]); } if (isHamiltonian(path, n)) { printf("YES\n"); } else { printf("NO\n"); } } return 0; } ``` 该程序使用邻接矩阵表示图,使用DFS算法汉密尔顿回路,使用isHamiltonian函数判断路径是否为汉密尔顿回路

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

归忆_AC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值