题目:点击打开链接
题目简化一下就是一个旅行者可以在任意一点出发,遍历所有顶点后回到原点,问可以走的最短路程。很著名的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; }