A few definitions first:
Definition 1 A graph G = (V, E) is called “dense” if for each pair of non-adjacent vertices u and v,
d(u) + d(v) ≥ n where n = |V| and d(•) denotes the degree of the vertex •.
Definition 2 A “Hamiltonian cycle” on G is a sequence of vertices (vi1
for all l ̸= h and {vil
, vil+1} is an edge of G.
The problem is: write a program that, given a dense indirect graph G = (V; E) as input, deter-
mines whether G admits a Hamiltonian cycle on G and outputs that cycle, if there is one, or outputs
‘N’ if there is none.
Input
The input file contains several descriptions of graphs (each one ending with a ‘%’), in the form:
n1
ui1
ui2
uj1
uj2
. . .
%
n2
ui1
ui2
. . .
%
where ni is the number of vertices (0 < ni ≤ 256) and uih
that there exists an edge between vertex uih
and uil
Output
For each test case, output a line that must contain the sequence of vertices that form a Hamiltonian
cycle in the form:
ui1
ui2
ui3
. . .
or containing:
N
Examples
Sample Input
4
1 2
2 3
2 4
3 4
3 1
%
6
1 2
1 3
1 6
3 2
3 4
5 2
5 4
6 5
6 4
%
Sample Output
1 2 4 3 1
1 3 2 5 4 6 1
题意:
给出一张无向图, 求出经过所有点一次又恰好返回原点的一条路径并输出, 如果没有, 打印N
题解:
经典的哈密顿路径问题了, 运用了路径还原+图中遍历+回溯, 而且此题只能用Dfs解决, 用Bfs将会非常麻烦.
为什么呢? 因为深度优先搜索是优先深度, 沿着一条道走到头为止, 这样的话很利于我们求得路径, 所以看来求路径的题往往需要用DFS
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef long long LL;
const LL maxn = 260;
int V;
bool G[maxn][maxn], vis[maxn]; //两点之间是否能走, 某点是否走过
int path[maxn];
bool Dfs(int from, int cnt){
//从from点出发, 当前该走第cnt点
path[cnt] = from;
if(cnt==V){
if(G[from][1]){
for(int i = 1; i <= cnt; i++)
cout << path[i] << " ";
cout << "1" << endl;
return true;
}
return false;
}
for(int i = 1; i <= V; i++){
if(G[from][i] && !vis[i]){
vis[i] = true; //无向图
if(Dfs(i, cnt+1)) return true;
vis[i] = false; //回溯
}
}
return false;
}
int main()
{
int a, b;
while(scanf("%d",&V)!=EOF){
ms(G, 0);
while(scanf("%d%d",&a,&b)==2){
G[a][b] = G[b][a] = 1;
}
getchar();
ms(vis, 0); ms(path, 0);
vis[1] = true;
if(!Dfs(1, 1)) cout << "N" << endl;
}
return 0;
}