• hdu3001Travelling


    参考了别人的代码   https://blog.csdn.net/u010372095/article/details/38474721

    深感自己的弱小

    这是tsp问题,和基本的tsp问题没什么大的区别,唯一的区别就是采用了三进制

    原来的二进制的某一位只能表示到达或没到达过,现在加了三进制,就能表示到达过几次了

    tsp问题网上的讲解我推荐这一篇    http://www.360doc.com/content/17/0826/11/36546539_682232069.shtml

    我个人感觉讲的算是很详细了,剩下的就是代码实现了。

    #include<iostream>
    #include<queue>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #include<string>
    using namespace std;
    #define ll long long
    #define se second
    #define fi first
    #define oo 0x3fffffff
    int n,m;
    int dp[15][60000];
    int dis[15][15];
    int three[12];
    int in[12];
    int tothree(int n);
    int main()
    {
        in[0] = 1;
        for(int i = 1; i <= 10; ++i)
            in[i] = in[i-1]*3;
    
        while(scanf("%d%d",&n,&m) != EOF)
        {
            for(int i = 0; i < n; ++i)
            {
                for(int j = 0; j < in[n]; ++j)
                    dp[i][j] = -1;
                for(int j = 0; j < n; ++j)
                    dis[i][j] = -1;
            }
            //cout << 1 << endl;
            for(int i = 0; i < m; ++i)
            {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                a --; b --;
                if(dis[a][b] == -1)
                    dis[a][b] = dis[b][a] = c;
                else
                    dis[a][b] = dis[b][a] = min(dis[a][b],c);
            }
    
            int minn = -1;
            for(int l = 1; l < in[n]; ++l)
            {
                int k = tothree(l);
                for(int i = 0; i < n; ++i)
                {
                    if(three[i])
                    {
                        if(k == 1)
                            dp[i][l] = 0;
                        if(dp[i][l] == -1)
                            continue;
                        if(k == n)
                        {
                            if(minn == -1) minn = dp[i][l];
                            else minn = min(minn,dp[i][l]);
                        }
    
                        for(int j = 0; j < n; ++j)
                        if(i != j && three[j] < 2 && dis[i][j] != -1)
                        {
                            int tog = l + in[j];
                            if(dp[j][tog] == -1)
                                dp[j][tog] = dp[i][l] + dis[i][j];
                            else
                                dp[j][tog] = min(dp[j][tog],dp[i][l] + dis[i][j]);
                        }
                    }
                }
            }
            printf("%d
    ",minn);
        }
    }
    int tothree(int n)
    {
        int k = 0;
        for(int i = 0; i < 10; ++i)
        {
            three[i] = n%3; n/=3; if(three[i]) k++;
        }
        return k;
    }
  • 相关阅读:
    MySQL数据库学习【第三篇】增删改查操作
    MySQL数据库学习【第二篇】基本操作和存储引擎
    MySQL数据库学习【第一篇】数据库安装
    python全栈开发基础【第二十七篇】IO模型
    python全栈开发基础【第二十六篇】(concurrent.futures模块、协程、Greenlet、Gevent)
    python基础之带参数装饰器和迭代器
    python基础之闭包函数与装饰器
    逻辑回归
    朴素贝叶斯
    决策树
  • 原文地址:https://www.cnblogs.com/mltang/p/9740108.html
Copyright © 2020-2023  润新知