求助最短 Hamilton 路径,悬关。
  • 板块学术版
  • 楼主qw1234321
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/3/26 21:44
  • 上次更新2024/3/26 22:05:52
查看原帖
求助最短 Hamilton 路径,悬关。
1060759
qw1234321楼主2024/3/26 21:44

rt. 时限 1s,TLE 了,加了注释,可读性应该不低。

#include<bits/stdc++.h>
#define int long long
#define il inline
#define rg register
namespace things{
	il int rd(){
		int f = 1, x = 0;
		char ch = getchar();
		while(ch < '0' || ch > '9'){
			if (ch == '-' ) f = -1;
			ch = getchar();
		}
		while(ch >= '0' && ch <= '9'){
			x = x * 10 + ch - '0';
			ch = getchar();
		}
		return x * f;
	}
	il int max(int x, int y){
		return std::max(x, y);
	}
	il int min(int a, int b){
		return std::min(a, b);
	}
}
using namespace things;
using namespace std;

int n, a[20][20], d[20][1 << 20];

/*
  di,j 现在点 i,状态为 j 的最短路径.
  1 已走、0 未走.
 */

signed main(){
	n = rd();
	for (rg int i = 0; i <= n - 1; i++){
		for (rg int j = 0; j <= n - 1; j++){
			a[i][j] = rd();
		}
	}
	memset(d, 0x3f, sizeof(d));
	d[0][1] = 0;//0->0 最短路为 0.
	for (rg int j = 1; j < (1 << n); j++){//The state.
		for (rg int i = 0; i <= n - 1; i++){//The vertex.
			//j 的除后 i 位的位置上必须全为 1,即全经过.
			if ((j >> i) & 1){
				for (rg int k = 0; k <= n - 1; k++){//The comed vertex.
					//上次的位置必须为 1,且 i 位置为 0,在 1 的位置中任选一个 k,取 min.
					if (((j ^ (1 << i)) >> k) & 1 && k != i) d[i][j] = min(d[i][j], d[k][(j ^ (1 << i))] + a[k][i]);//从 k 转移过来到 i.
				}
			}
		}
	}
	printf("%lld", d[n - 1][(1 << n) - 1]);//经过所有点,最后到 n - 1.
	return 0;
}
2024/3/26 21:44
加载中...