1 solutions

  • 3
    @ 2025-6-28 8:02:16
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    const int N = 21, INF = 2e9;
    // f[i][s]:当前在点i,已访问状态为s时的最短H路径长度
    int f[N][(1 << N)];
    int g[N][N];
    
    int main() {
    	int n;
    	cin >> n;
    	// 下标尽量保证与题目一致。而且从0开始更容易做位运算。
    	for (int i = 0; i < n; i++)
    		for (int j = 0; j < n; j++)
    			cin >> g[i][j];
    
    	int U = (1 << n) - 1;
    	fill(&f[0][0], &f[n][U + 1], INF);
    
    	f[0][1] = 0; // 非常重要的初始值!
    	for (int s = 1; s <= U; s++)
    		for (int u = 0; u < n; u++) {
    			// 枚举到一个已被访问的点,再往下转移
    			if (((s >> u) & 1) == 0) continue;
    			// f[u][s]==INF表示
    			// 当前访问了u且整张图的访问状态是s,但路径长度竟然是不存在,
    			// 说明这个状态是不合法的(u还未被纳入任何一条H路径中)。
    			if (f[u][s] == INF) continue;
    			// 枚举未被访问的点
    			for (int v = 0; v < n; v++)
    				if (((s >> v) & 1) == 0)
    					f[v][s | (1 << v)] = min(f[v][s | (1 << v)], f[u][s] + g[u][v]);
    		}
    	
    	cout << f[n - 1][U]; // 终点是n-1,状态是全集(全都被访问过)
    
    	return 0;
    }
    
    • @ 2025-6-28 11:23:35

      提问:

      这里不开long long在第三层循环for (int v = 0; v < n; v++)中遇到f[u][s]==g[u][v]==inf会不会爆掉(2e9+2e9似乎会爆掉)

    • @ 2025-8-21 21:00:18

      @ 在代码中,g[u][v]只有在输入的时候被修改,题目中也说明了,输入小于10710^7,所以不会越界。

    • @ 2025-8-21 21:01:27

      @ 最大值是2e9+1e7=20100000002e9+1e7=2010000000,而int最大值是21474836472147483647,所以不会溢出。

  • 1

Information

ID
400
Time
1000ms
Memory
512MiB
Difficulty
4
Tags
# Submissions
23
Accepted
17
Uploaded By