zoukankan      html  css  js  c++  java
  • CH 0103 最短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路径的长度。

    样例输入:

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

    样例输出:

    4

    解题报告:

    第一次接触状压dp,问了室友,大概明白就是把所有状态枚举,然后找到最短的那个状态

    但是不是特别懂,以后再回头来看看

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=20;
    int f[1<<N][N],w[N][N],n;
    int main()
    {
        scanf("%d",&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=1;i<(1<<n);i++)
        {///总共1<<n种情况
            for(int j=0;j<n;j++)
            {///遍历0~n
                if(i>>j&1)
                {///如果这个点已经被经过了
                    for(int k=0;k<n;k++)
                    {///遍历当前路径上的每个点
                        if(i^(1<<j)>>k&1)///如果这个点曾经被经过过
                            f[i][j]=min(f[i][j],f[i^1<<j][k]+w[k][j]);
                            ///i^(1<<j):假装j还没经过,进行状态转移
                    }
                }
            }
        }
        printf("%d
    ",f[(1<<n)-1][n-1]);
        return 0;
    }



  • 相关阅读:
    Quartz
    WebService
    JavaMail
    安装phpnow服务[Apache_pn]提示失败的解决方法
    idea安装激活
    csdn下载
    java解析json串常识
    Oracle错误——ORA-03113:通信通道的文件结尾
    SSM(Maven集成)
    SpringMVC的拦截器
  • 原文地址:https://www.cnblogs.com/acm-cyz/p/11446810.html
Copyright © 2011-2022 走看看