7-2 TSP问题 给出一个n个顶点的带权无向图,请寻找一条从顶点1出发,遍历其余顶点一次且仅一次、最后回到顶点1的最小成本的回路——即最短Hamilton回路。 输入格式: 第一行,两个正整数 n 和 e ,0 < n ≤ 21 ,n < e < n×n/2 ,表示该无向图的顶点个数,以及边的数量。顶点编号是1~n 第二行至e+1行,每行3个非负整数 u , v 和 w ,分别表示顶点u与顶点v之间有一条边,其权值为w 。 输出格式: 如果存在Hamilton回路,请输出回路的路径长度。 如果不存在Hamilton回路,请输出“ no Hamilton circuit”(不包含引号) c++代码
时间: 2024-03-20 15:44:10 浏览: 53
带权图的多种算法(有向图,无向图,Dijkstra算法,到每个顶点的最短距离算法,佛洛依德算法(Floyd),找出每对顶点的最短路径,带权重无向图最小生成树,prim算法,Kruskal算法求最小生成树)java实现,有注释
5星 · 资源好评率100%
下面是 c++ 代码实现,使用了状态压缩和 bitset 加速状态转移:
```c++
#include <iostream>
#include <cstring>
#include <bitset>
using namespace std;
const int N = 21, INF = 0x3f3f3f3f;
int n, m;
int w[N][N];
int f[1 << N][N];
int main()
{
cin >> n >> m;
memset(w, 0x3f, sizeof w);
while (m -- )
{
int a, b, c;
cin >> a >> b >> c;
w[a - 1][b - 1] = w[b - 1][a - 1] = min(w[a - 1][b - 1], c);
}
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]);
int res = INF;
for (int i = 0; i < n; i ++ )
res = min(res, f[(1 << n) - 1][i] + w[i][0]);
if (res == INF) puts("no Hamilton circuit");
else cout << res << endl;
return 0;
}
```
时间复杂度为 $O(n^22^n)$,空间复杂度为 $O(n2^n)$。
阅读全文