zoukankan      html  css  js  c++  java
  • 最短Hamilton路径

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

    输入格式

    第一行输入整数n。

    接下来n行每行n个整数,其中第ii行第jj个整数表示点ii到jj的距离(记为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路径的长度。

    数据范围

    1n20  1≤n≤20
    0a[i,j]107  0≤a[i,j]≤107

    输入样例:

    5
    0 2 4 5 1
    2 0 6 5 3
    4 6 0 8 3
    5 5 8 0 5
    1 3 3 5 0
    

    输出样例:

    18


    f[i,j] i表示是否走过,比如 i = 0101,表示走过第一个点和第三个点
    状态转移 f[i][j] = min(f[i][j],f[i ^ (1 << j)][k] + w[j][k])
    i ^ (1 << j):i的第j位取反,表示j还未曾经过,
    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N = 20;
    const int M = 1 << 20;
    int f[M][N],w[N][N];
    int n;
    signed main(){
        //freopen("in","r",stdin);
        ios::sync_with_stdio(0);
        cin >> n;
        for(int i = 0; i < n; i++)
           for(int j = 0; j < n; j++)
               cin >> w[i][j];
        memset(f,0x3f, sizeof(f));
        f[1][0] = 0;
        for(int i = 0; i < 1 << n; i++){
            for(int j = 0; j < n; j++)
                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]);
                        }
                }
        }
        cout << f[(1 << n) - 1][n - 1];
        return 0;
    }
    View Code


  • 相关阅读:
    Vue(小案例_vue+axios仿手机app)_go实现退回上一个路由
    nyoj 635 Oh, my goddess
    nyoj 587 blockhouses
    nyoj 483 Nightmare
    nyoj 592 spiral grid
    nyoj 927 The partial sum problem
    nyoj 523 亡命逃窜
    nyoj 929 密码宝盒
    nyoj 999 师傅又被妖怪抓走了
    nyoj 293 Sticks
  • 原文地址:https://www.cnblogs.com/xcfxcf/p/12353391.html
Copyright © 2011-2022 走看看