【ACMclub周赛5】Problem E——TSP旅行商问题

来源:互联网 发布:淘宝天猫历史价格 编辑:程序博客网 时间:2024/06/05 19:40

题目:点击打开链接

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




原创粉丝点击