zoukankan      html  css  js  c++  java
  • 哈密顿绕行世界问题 (dfs)

    一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市。 

    Input前20行的第i行有3个数,表示与第i个城市相邻的3个城市.第20行以后每行有1个数m,m<=20,m>=1.m=0退出. 
    Output输出从第m个城市出发经过每个城市1次又回到m的所有路线,如有多条路线,按字典序输出,每行1条路线.每行首先输出是第几条路线.然后个一个: 后列出经过的城市.参看Sample output 
    Sample Input

    2 5 20
    1 3 12
    2 4 10
    3 5 8
    1 4 6
    5 7 19
    6 8 17
    4 7 9
    8 10 16
    3 9 11
    10 12 15
    2 11 13
    12 14 20
    13 15 18
    11 14 16
    9 15 17
    7 16 18
    14 17 19
    6 18 20
    1 13 19
    5
    0

    Sample Output

    1:  5 1 2 3 4 8 7 17 18 14 15 16 9 10 11 12 13 20 19 6 5
    2:  5 1 2 3 4 8 9 10 11 12 13 20 19 18 14 15 16 17 7 6 5
    3:  5 1 2 3 10 9 16 17 18 14 15 11 12 13 20 19 6 7 8 4 5
    4:  5 1 2 3 10 11 12 13 20 19 6 7 17 18 14 15 16 9 8 4 5
    5:  5 1 2 12 11 10 3 4 8 9 16 15 14 13 20 19 18 17 7 6 5
    6:  5 1 2 12 11 15 14 13 20 19 18 17 16 9 10 3 4 8 7 6 5
    7:  5 1 2 12 11 15 16 9 10 3 4 8 7 17 18 14 13 20 19 6 5
    8:  5 1 2 12 11 15 16 17 18 14 13 20 19 6 7 8 9 10 3 4 5
    9:  5 1 2 12 13 20 19 6 7 8 9 16 17 18 14 15 11 10 3 4 5
    10:  5 1 2 12 13 20 19 18 14 15 11 10 3 4 8 9 16 17 7 6 5
    11:  5 1 20 13 12 2 3 4 8 7 17 16 9 10 11 15 14 18 19 6 5
    12:  5 1 20 13 12 2 3 10 11 15 14 18 19 6 7 17 16 9 8 4 5
    13:  5 1 20 13 14 15 11 12 2 3 10 9 16 17 18 19 6 7 8 4 5
    14:  5 1 20 13 14 15 16 9 10 11 12 2 3 4 8 7 17 18 19 6 5
    15:  5 1 20 13 14 15 16 17 18 19 6 7 8 9 10 11 12 2 3 4 5
    16:  5 1 20 13 14 18 19 6 7 17 16 15 11 12 2 3 10 9 8 4 5
    17:  5 1 20 19 6 7 8 9 10 11 15 16 17 18 14 13 12 2 3 4 5
    18:  5 1 20 19 6 7 17 18 14 13 12 2 3 10 11 15 16 9 8 4 5
    19:  5 1 20 19 18 14 13 12 2 3 4 8 9 10 11 15 16 17 7 6 5
    20:  5 1 20 19 18 17 16 9 10 11 15 14 13 12 2 3 4 8 7 6 5
    21:  5 4 3 2 1 20 13 12 11 10 9 8 7 17 16 15 14 18 19 6 5
    22:  5 4 3 2 1 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5
    23:  5 4 3 2 12 11 10 9 8 7 6 19 18 17 16 15 14 13 20 1 5
    24:  5 4 3 2 12 13 14 18 17 16 15 11 10 9 8 7 6 19 20 1 5
    25:  5 4 3 10 9 8 7 6 19 20 13 14 18 17 16 15 11 12 2 1 5
    26:  5 4 3 10 9 8 7 17 16 15 11 12 2 1 20 13 14 18 19 6 5
    27:  5 4 3 10 11 12 2 1 20 13 14 15 16 9 8 7 17 18 19 6 5
    28:  5 4 3 10 11 15 14 13 12 2 1 20 19 18 17 16 9 8 7 6 5
    29:  5 4 3 10 11 15 14 18 17 16 9 8 7 6 19 20 13 12 2 1 5
    30:  5 4 3 10 11 15 16 9 8 7 17 18 14 13 12 2 1 20 19 6 5
    31:  5 4 8 7 6 19 18 17 16 9 10 3 2 12 11 15 14 13 20 1 5
    32:  5 4 8 7 6 19 20 13 12 11 15 14 18 17 16 9 10 3 2 1 5
    33:  5 4 8 7 17 16 9 10 3 2 1 20 13 12 11 15 14 18 19 6 5
    34:  5 4 8 7 17 18 14 13 12 11 15 16 9 10 3 2 1 20 19 6 5
    35:  5 4 8 9 10 3 2 1 20 19 18 14 13 12 11 15 16 17 7 6 5
    36:  5 4 8 9 10 3 2 12 11 15 16 17 7 6 19 18 14 13 20 1 5
    37:  5 4 8 9 16 15 11 10 3 2 12 13 14 18 17 7 6 19 20 1 5
    38:  5 4 8 9 16 15 14 13 12 11 10 3 2 1 20 19 18 17 7 6 5
    39:  5 4 8 9 16 15 14 18 17 7 6 19 20 13 12 11 10 3 2 1 5
    40:  5 4 8 9 16 17 7 6 19 18 14 15 11 10 3 2 12 13 20 1 5
    41:  5 6 7 8 4 3 2 12 13 14 15 11 10 9 16 17 18 19 20 1 5
    42:  5 6 7 8 4 3 10 9 16 17 18 19 20 13 14 15 11 12 2 1 5
    43:  5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5
    44:  5 6 7 8 9 16 17 18 19 20 1 2 12 13 14 15 11 10 3 4 5
    45:  5 6 7 17 16 9 8 4 3 10 11 15 14 18 19 20 13 12 2 1 5
    46:  5 6 7 17 16 15 11 10 9 8 4 3 2 12 13 14 18 19 20 1 5
    47:  5 6 7 17 16 15 11 12 13 14 18 19 20 1 2 3 10 9 8 4 5
    48:  5 6 7 17 16 15 14 18 19 20 13 12 11 10 9 8 4 3 2 1 5
    49:  5 6 7 17 18 19 20 1 2 3 10 11 12 13 14 15 16 9 8 4 5
    50:  5 6 7 17 18 19 20 13 14 15 16 9 8 4 3 10 11 12 2 1 5
    51:  5 6 19 18 14 13 20 1 2 12 11 15 16 17 7 8 9 10 3 4 5
    52:  5 6 19 18 14 15 11 10 9 16 17 7 8 4 3 2 12 13 20 1 5
    53:  5 6 19 18 14 15 11 12 13 20 1 2 3 10 9 16 17 7 8 4 5
    54:  5 6 19 18 14 15 16 17 7 8 9 10 11 12 13 20 1 2 3 4 5
    55:  5 6 19 18 17 7 8 4 3 2 12 11 10 9 16 15 14 13 20 1 5
    56:  5 6 19 18 17 7 8 9 16 15 14 13 20 1 2 12 11 10 3 4 5
    57:  5 6 19 20 1 2 3 10 9 16 15 11 12 13 14 18 17 7 8 4 5
    58:  5 6 19 20 1 2 12 13 14 18 17 7 8 9 16 15 11 10 3 4 5
    59:  5 6 19 20 13 12 11 10 9 16 15 14 18 17 7 8 4 3 2 1 5
    60:  5 6 19 20 13 14 18 17 7 8 4 3 10 9 16 15 11 12 2 1 5

     解题思路:

    思路就是深度搜索啊,用栈来模拟递归过程,因为要按照字典序,所以排序时要倒着排。

    从一个顶点出发,有三个与其相邻的顶点,所以从一点出发有三条路,所以按照排好的顺序来挨着走,记得每次往外走的时候记下已经走过的路,防止一个点重复走多次。

    另外总共有二十个顶点,每个顶点让走一次,所以可以直接判断走了20步,并且走二十步之后的下一步能走到起点,就能找到满足题意的路。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <stack>
    #include <queue>
    
    using namespace std;
    
    typedef struct node{
        int sequ[21];
        int num;
    }sequence;
    
    stack<sequence> s;
    sequence now,next;
    int a[20][3];
    int m;
    int printcount=1;
    int flag[22];
    
    bool judge(){
        if(now.sequ[now.num-1]==a[m-1][0]||now.sequ[now.num-1]==a[m-1][1]||now.sequ[now.num-1]==a[m-1][2]){
            return true;
        }else{
            return false;
        }
    }
    
    
    void dfs(int m){
        while(!s.empty()){
            now=s.top(); s.pop();
            if(now.num==20&& judge()){
                printf("%d:  ",printcount++);
                for(int i=0;i<20;i++){
                    printf("%d ",now.sequ[i]);
                }
                printf("%d
    ",m);
            }else{
                memset(flag,0,sizeof(flag));
                for(int i=0;i<now.num;i++){
                    flag[now.sequ[i]]=1;
                }
                for(int i=0;i<3;i++){
                    if(flag[a[now.sequ[now.num-1]-1][i]]==0){
                        now.sequ[now.num]=a[now.sequ[now.num-1]-1][i];
                        now.num++;
                        s.push(now);
                        now.num--;
                    }
                }
            }
        }
    }
    
    int main()
    {
        for(int i=0;i<20;i++){
            for(int j=0;j<3;j++){
                scanf("%d",&a[i][j]);
            }
            if(a[i][0]<a[i][1]){swap(a[i][0],a[i][1]);}
            if(a[i][1]<a[i][2]){swap(a[i][1],a[i][2]);}
            if(a[i][0]<a[i][1]){swap(a[i][0],a[i][1]);}
        }
        while(scanf("%d",&m)&&m){
            printcount=1;
            now.num=0;
            now.sequ[now.num++]=m;
            s.push(now);
            flag[m]=1;
            dfs(m);
        }
        return 0;
    }
  • 相关阅读:
    转储文件知多少
    [原]你知道怎么使用DebugView查看内核调试信息吗?
    [原]排错实战——通过对比分析sysinternals事件修复程序功能异常
    [原]排错实战——VS清空最近打开的工程记录
    [原]排错实战——使用process explorer替换任务管理器
    [原]排错实战——解救加载调试符号失败的IDA
    [原]调试实战——使用windbg调试DLL卸载时的死锁
    [原]调试实战——使用windbg调试TerminateThread导致的死锁
    [原]使用64位的编译工具进行编译
    [原]C++新标准之std::ratio
  • 原文地址:https://www.cnblogs.com/TWS-YIFEI/p/9075439.html
Copyright © 2011-2022 走看看