Hamilton路径

描述

给出一个连通的有向图,求图中顶点 1 到顶点 n 的、经过其余顶点一次且仅一次的最短路径及其长度。

输入描述

第一行是两个整数 N(1≤N≤40),E(N<E<200),N 表示顶点个数,E 表示弧的数量。

接下来 E 行,每行是空格分隔的 3 个整数 u,v,l,分别表示从顶点 u 发出一条长度为 l 的弧到顶点 v 。1≤u,v≤N,0<l≤100

注意:可能存在重边。

输出描述

如果不存该路径,一行结果:No solution

否则,两行结果:第 1 行,该最短路的长度;第 2 行,从顶点 1 到顶点 n 的最短路,顶点之间用一个空格分隔,要求按路径的顶点次序,前一个顶点必须有弧指向后一个顶点。

用例输入 1 

5 12
1 2 23
1 3 35
1 4 5
2 3 58
2 4 8
2 5 76
3 2 33
3 4 2
3 5 75
4 2 95
4 3 34
4 5 85

用例输出 1 

140
1 2 4 3 5 
#include <iostream>
using namespace std;

const int INF = 0x3f3f3f3f;
int aim[45][2500];
int len[45][2500];   // 分别存储目标顶点编号和边长
int a_size[45];                      // 记录每个顶点的邻接边数量

int q[45];                         // 存储当前路径的顶点序列
int ww[45];                        // 存储最短哈密顿路径的顶点序列

// 顶点数、边数、起点、终点、边的长度、当前最短路径的长度
int N, E, u, v, l, way;

bool book[45];                      // 记录顶点是否被访问过的数组

// 深度优先搜索函数
void dfs(int i,int road,int num){
    if(road>way)
        return;

    if(i==N&&num==N){
        if(road<way){
            way=road;
            for(int j=0;j<N;++j)
                ww[j]=q[j];
        }
        return;
    }

    for(int j=0;j<a_size[i];j++){
        if (!book[aim[i][j]]){
            book[aim[i][j]]=true;
            road+=len[i][j];
            q[num]=aim[i][j];

            dfs(aim[i][j],road,num+1);

            road-=len[i][j];
            book[aim[i][j]]=false;
        }
    }
}

int main(){
	
    cin>>N>>E;
    for(int i=1;i<=E;i++){
        cin>>u>>v>>l;
        aim[u][a_size[u]++]=v;
        len[u][a_size[u]-1]=l;
    }

    way=0x3f3f3f3f;
    book[1]=true;
    q[0]=1;

    dfs(1,0,1);

    if(way==0x3f3f3f3f){
        cout<<"No solution"<<endl;
        return 0;
    }

    cout<<way<<endl;
    for(int i=0;i<N;i++)
        cout<<ww[i]<< " ";
    cout<<endl;

    return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值