题目链接:http://poj.org/problem?id=3311
分析:由于题中明确说了两个城市间的直接可达路径(即不经过其它城市结点)不一定是最短路径,所以需要借助邻接矩阵首先求出任意两个城市间的最短距离(因为这里的点可以多次遍历,并没有次数限制,所以才能用floyd的,如果有次数限制x的话,就不能用floyd预处理,而应该用x进制的状态压缩了)。这一步骤使用Floyd最短路径算法即可。然后,在此基础上来求出遍历各个城市后回到出发点的最短路径的距离,即求解TSP问题。
考虑搜索算法:这种解法其实就是计算排列子集树的过程。从0点出发,要求遍历1,2,3点后回到0点。以不同的顺序来依次遍历1,2,3点就会导出不同的路径(0->1->2->3->0;0->1->3->2->0等等),总共有3!=6条路径需要考虑,从中选出最短的那条就是所求。搜索解法的时间复杂度为 O(n!) 。
思索:仔细观察搜索解法的过程,其实是有很多重复计算的。比如从0点出发,经过1,2,3,4,5点后回到0点。那么0->1->2->(3,4,5三个点的排列)->0与0->2->1->(3,4,5三个点的排列)->0就存在重复计算(3,4,5三点的排列)->0路径集上的最短路径。只要我们能够将这些状态保存下来就能够降低一部分复杂度。
#include
using namespace std;
int dp[65540][20];
int a[20][20];
int main()
{
int n;
while (cin>>n && n)
{
for (int i=0; i<=n; i++)
for (int j=0; j<=n; j++) cin>>a[i][j];
for (int k=0; k<=n; k++)
for (int i=0; i<=n; i++)
for (int j=0; j<=n; j++)
a[i][j] = min(a[i][j],a[i][k]+a[k][j]);
int m = (1<