TSP模板

算法大意:从一个起点出发,到达所有需要达到的点,再回到本身,求最短路

法一:用状态压缩思想

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cmath>

using namespace std;

int n;

struct edge{

    int x;

    int y;

}a[20];

int temp[20][1<<16],dis[20][20],best[1<<16];

const int inf = 0x3f3f3f3f;

int main()

{

    while(~scanf("%d",&n)){

        for(int i = 0; i < n ; i++)

            scanf("%d%d",&a[i].x,&a[i].y);

        int len = 0;

        int maxn = (1<<n)-1;

        for(int i = 0 ; i < n ; i++)

            for(int j = 0; j <n ; j++)

                dis[j][i] = dis[i][j] = ceil(sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)));

        for(int i = 0 ; i <= maxn; i++)

            best[i]= inf;

        for(int i = 0 ; i <= n ; i++)

            for(int j = 0 ; j <= maxn; j++)

                temp[i][j] = inf;

        temp[0][1] =0;//现在为状态1,当前位置在0

        for(int i = 0 ; i <= maxn ; i++){

            for(int j = 0 ; j < n ; j++){

                if(i&(1<<j)){

                    best[i] = min(best[i],temp[j][i]+dis[j][0]);

                    for(int k = 0 ; k < n ; k++)

                        if(!(i&(1<<k)))

                            temp[k][i|(1<<k)] = min(temp[k][i|(1<<k)],temp[j][i]+dis[j][k]);

                }

            }

        }

        printf("%d\n",best[maxn]);

    }

    return 0;

}

  

法二:

上面方法复杂度也没降很多。。直接暴力2^n*n^2感觉写法简单多了

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

const int inf = 0x3f3f3f3f;

int n,m;

int dp[22222][15];

int d[22][22];

int main()

{

    while(~scanf("%d%d",&n,&m)){

        for(int i = 0 ; i < 1 << n ; i++){

            for(int j = 0 ; j <= n ; j++){

                dp[i][j] = inf;

            }

        }

    //算出各个点之间的距离d[i][j]

    dp[(1<<n)-1][0] = 1//当前位于0总共的集合为1<<n-1

    for(int i = (1<<n)- 2; i >= 0 ; i--){//遍历所有的情况

        for(int j = 0 ; j < n ; j++){//当前在j

            for(int k = 0 ; k < n; k++){

                if(!(i>>k & 1))//下一步去k,如果k位值为0说明还没有走过

                    dp[i][j] = min(dp[i][j],dp[i|1<<k][k] + d[j][k]);//更新

            }

        }

    }

    printf("%d\n",dp[0][0]);

    }

}

  

你可能感兴趣的:(模板)