题目:点击打开链接
题目简化一下就是一个旅行者可以在任意一点出发,遍历所有顶点后回到原点,问可以走的最短路程。很著名的NP-HARD旅行商问题。
TSP问题最简单的求解方法是枚举法,时间复杂度是O(n!),
其余的解都是无法证明的最优近似解,但是可以直接拿来用,此外还有模拟退火,floyd+DP,Edmonds-Johnson等各种方法,贴个模板吧,可以用poj 2404练一下手。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define MAX_NUM 0x3f3f3f3f
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
using namespace std;
int nstations, ntrails;
int grid[20][20];
int num;
int part_result;
int degree[20];
int nodes[20];
int used[20];
int search(int start, int end, int sum)
{
int i;
if (start == end)
{
part_result = MIN(sum, part_result);
return 0;
}
if (used[nodes[start]] == 0)
{
used[nodes[start]] = 1;
for (i = start + 1; i < num; ++i)
{
if (used[nodes[i]] == 1)
continue;
if (sum + grid[nodes[start]][nodes[i]] >= part_result)
continue;
used[nodes[i]] = 1;
search(start + 1, end, sum + grid[nodes[start]][nodes[i]]);
used[nodes[i]] = 0;
}
used[nodes[start]] = 0;
return 0;
}
return search(start + 1, end, sum);
}
int main()
{
int i, j, k;
int node0, node1, len;
int tlen;
int result;
while (cin>>nstations && nstations!=0)
{
cin>>ntrails;
result = 0;
for (i = 0; i <= nstations; ++i)
{
degree[i] = 0;
used[i] = 0;
for (j = 0; j <= nstations; ++j)
grid[i][j] = MAX_NUM;
}
for (i = 0; i < ntrails; ++i)
{
scanf("%d %d %d", &node0, &node1, &len);
result += len;
degree[node0]++;
degree[node1]++;
grid[node0][node1] = grid[node1][node0] = MIN(grid[node1][node0], len);
}
for (k = 1; k <= nstations; ++k)
{
for (i = 1; i <= nstations; ++i)
{
for (j = 1; j <= nstations; ++j)
{
grid[i][j] = MIN(grid[i][j], grid[i][k] + grid[k][j]);
}
}
}
num = 0;
for (k = 1; k <= nstations; ++k)
{
if (degree[k] & 1)
nodes[num++] = k;
}
part_result = MAX_NUM;
search(0, num, 0);
result += part_result;
cout<<result<<endl;
}
return 0;
}