• CH0103 最短Hamilton路径


    描述

    给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径。 Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次。

    输入格式

    第一行一个整数n。

    接下来n行每行n个整数,其中第i行第j个整数表示点i到j的距离(一个不超过10^7的正整数,记为a[i,j])。

    对于任意的x,y,z,数据保证 a[x,x]=0,a[x,y]=a[y,x] 并且 a[x,y]+a[y,z]>=a[x,z]。

    输出格式

    一个整数,表示最短Hamilton路径的长度。

    样例输入

    4
    0 2 1 3
    2 0 2 1
    1 2 0 1
    3 1 1 0

    样例输出

    4

    样例解释

    从0到3的Hamilton路径有两条,0-1-2-3和0-2-1-3。前者的长度为2+2+1=5,后者的长度为1+2+1=4

    题目地址:地址(进阶指南p6)


    个人思路:

    • 裸的状压DP
    • 适合初学者学习

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int maxn=20;
    int f[1<<maxn][maxn],w[maxn][maxn],n;
    int main(){
    	cin>>n;
    	for(int i=0;i<n;i++)
    		for(int j=0;j<n;j++)
    			scanf("%d",&w[i][j]);
    	memset(f,0x3f,sizeof(f));
    	f[1][0]=0;
    	for(int i=2;i<(1<<n);i++)//当前已经经过的路径
    		for(int j=0;j<n;j++)//遍历当前路径上的每个点
    		if(i>>j&1)//如果这个点已经被经过了
    			for(int k=0;k<n;k++)//遍历当前路径上的每个点
    			if(j!=k&&i>>k&1)//如果这个点之前就被经过过
    			f[i][j]=min(f[i][j],f[i^(1<<j)][k]+w[k][j]);//i^(1<<j):假装j还没经过,进行状态转移
    	cout<<f[(1<<n)-1][n-1]<<endl;
    	return 0;
    }
  • 相关阅读:
    8月的list
    hdu 2853
    【问题交流】JAVA 基础 switch 执行顺序的问题
    h5/css动态旋转木马源码
    javascript系列丛书之读后感
    java运行闪退,报错如下,是因为ole32.dll的问题吗?
    js
    切换为文本框编辑状态,点击空白区域保存修改
    前端工程师源码分享:html5 2d 扇子
    2017武汉马拉松4月9日开跑啦~~~
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680671.html
Copyright © 2020-2023  润新知