• HDU 3001 Traveling(状压DP)


    题目大意:10个点的TSP问题,但是要求每个点最多走两边,不是只可以走一次,所以要用三进制的状态压缩解决这个问题。可以预处理每个状态的第k位是什么。

    原代码链接:http://blog.csdn.net/accry/article/details/6607703

    3进制,代表走过这个点的次数

    #include <cstdio>
    #include<cstdlib>
    #include <cstring>
    #define INF 0x1f1f1f1f
    #define min(a,b) (a) < (b) ? (a) : (b)
    using namespace std;
    
    int N,M;
    int tri[12] = {0,1,3,9,27,81,243,729,2187,6561,19683,59049};
    int dig[59050][11];  //dig[state][k_dig]  状态state的第k位是多少
    int edge[11][11],dp[59050][11];
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("C:\Users\Zmy\Desktop\in.txt","r",stdin);
    //    freopen("C:\Users\Zmy\Desktop\out.txt","w",stdout);
    #endif // ONLINE_JUDGE
    
    //
    //    char stit[200];
    //    for (int i=0;i<12;i++)
    //    {
    //        itoa(tri[i],stit,3);
    //        puts(stit);
    //    }
    
    
        for(int i = 0; i < 59050; ++i)
        {
            int t = i;
            for(int j = 1; j <= 10; ++j)
            {
                dig[i][j] = t%3;
                t /= 3;
                if(t == 0)break;
            }
        }
    
    //    itoa(123,stit,3);
    //    puts(stit);
    //
    //    puts("tst");
    //    for(int j = 1; j <= 10; ++j)
    //        printf("%d ",dig[123][j]);
    
    
        while(scanf("%d%d",&N,&M) != EOF)
        {
            memset(edge,INF,sizeof(edge));
    
            int a,b,c;
            int m2=M;
            while(M --)
            {
                scanf("%d%d%d",&a,&b,&c);
                if(c < edge[a][b])edge[a][b] = edge[b][a] = c;
            }
    
    //        for (int i=1;i<=N;i++)
    //        {
    //            for (int j=1;j<=N;j++)
    //                printf("%d ",edge[i][j]);
    //            puts("");
    //        }
    
            memset(dp,INF,sizeof(dp));
    
            for(int i = 1; i <= N; ++i)dp[tri[i]][i] = 0;
    
            int ans = INF;
            for(int S = 0; S < tri[N+1]; ++S)
            {
                int visit_all = 1;
                for( int i = 1; i <= N; ++i)
                {
                    if(dig[S][i] == 0)visit_all = 0;
                    if(dp[S][i] == INF)continue;
    
                    for(int j = 1; j <= N; ++j)
                    {
                        if(i == j)continue;
                        if(edge[i][j] == INF ||dig[S][j] >= 2)continue;
                        int newS = S + tri[j];
                        dp[newS][j] =min(dp[newS][j],dp[S][i] + edge[i][j]);
                    }
                }
    
                if(visit_all)
                {
                    for(int j = 1; j <= N; ++j)
                        ans = min(ans,dp[S][j]);
                }
    
            }
    
            if(ans == INF)
            {
                puts("-1");
                continue;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

      


  • 相关阅读:
    InnoSetup 打包代码 检测.netFramework
    PartialView中的页面重定向
    Cocos2dx 学习之引擎介绍
    30个高质量的免费jquery滑块PSD文件
    HBase Shell
    图灵百年诞辰 1912.6.232012.6.23
    常用的数据分页技术及比较
    Cocos2dx学习之windows 7的visual studo 2010开发环境安装
    C#实现简易ajax调用后台方法
    AJAX(Professional ASP.NET MVC 3
  • 原文地址:https://www.cnblogs.com/s1124yy/p/5520986.html
Copyright © 2020-2023  润新知