Hamiltonian Cycle UVA - 775 (DFS 路径还原)

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;
}

猜你喜欢

转载自blog.csdn.net/a1097304791/article/details/87968697