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

    今天第一次在(AcWing)这个网站上做题,来发一下此网站的第一篇题解

    AcWing 91. 最短Hamilton路径


    思路

    直接枚举的话时间复杂度为(O(n*n!))
    复杂度显然爆炸,所以我们用二进制枚举,这样就可以把复杂度降到(O(n * 2^{n}))
    我们用(f[i][j])表示走到j这个点,经过点的状态为(i)((i)是二进制数,若(i)的二进制数下某一位为(1)则表示这个点已经走过了)
    显然,转移方程为:(f[i][j] = min(f[i][j], f[i ^ 1 << j][k] + a[k][j]))(k)为上一步走的点,(i)中必须包含(k)的时候才可以转移,这里加一个判断就好了)
    最后的答案就存在(f[(1<<n)-1][n-1])中(因为我这里是从(0)开始编号的)


    代码

    //知识点:二进制状态压缩 
    /*
    By:Loceaner
    */
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    inline int read() {
    	char c = getchar();
    	int x = 0, f = 1;
    	for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    	for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
    	return x * f;
    }
    
    const int N = 20;
    
    int n, a[N][N], f[1 << N][N];
     
    int main() {
    	n = read();
    	for(int i = 0; i < n; i++) 
    		for(int j = 0; j < n; j++)
    			a[i][j] = read();
    	memset(f, 0x3f, sizeof(f));
    	f[1][0] = 0;
    	for(int i = 1; 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] + a[k][j]);
    	cout << f[(1 << n) - 1][n - 1] << '
    ';
    	return 0;
    }
    
  • 相关阅读:
    [运维-安全]CentOS7.0环境下安装kangle和easypanel
    (转)FastDFS文件存储
    使用mybatis-generator-core自动生成代码
    SSM框架中常用的配置文件
    Spring MVC文件上传和下载
    Spring MVC-拦截器
    Spring MVC之JSON数据交互和RESTful的支持
    Spring MVC数据绑定(二)
    Spring MVC数据绑定(一)
    Spring MVC简介
  • 原文地址:https://www.cnblogs.com/loceaner/p/11656478.html
Copyright © 2011-2022 走看看