【ACMclub周賽5】Problem E——TSP旅行商問題
阿新 • • 發佈:2019-02-04
題目簡化一下就是一個旅行者可以在任意一點出發,遍歷所有頂點後回到原點,問可以走的最短路程。很著名的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; }