码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3001【状态压缩DP】

时间:2015-11-06 22:20:44      阅读:269      评论:0      收藏:0      [点我收藏+]

标签:

题意:

给n个点m条无向边。

要求每个点最多走两次,要访问所有的点给出要求路线中边的权值总和最小。

思路:

三进制状态压缩DP,0代表走了0次,1,2类推。

第一次弄三进制状态压缩DP,感觉重点是对数据的预处理,利用数组分解各个位数,从而达到类似二进制的目的。

然后就是状态的表示,dp[s][i]表示状态s时到达i的最优值。

状态转移也一目了然,不废话。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
int pho[15][15];
int unit[12];
int dic[60000][11];
int dp[60000][11];
inline void init()
{
    memset(dic,0,sizeof(dic));
    unit[0]=1;
    for(int i=1;i<=11;i++)
    {
        unit[i]=3*unit[i-1];
    }
    for(int i=0;i<=59049;i++)
    {
        int tmp=i;
        for(int j=0;tmp;j++)
        {
            dic[i][j]=tmp%3;
            tmp/=3;
        }
    }
}
int main()
{
    int n,m;
    init();
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                pho[i][j]=inf;
            }
            pho[i][i]=0;
        }
        for(int i=1;i<=m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            pho[a][b]=pho[b][a]=min(pho[a][b],c);
        }
        int ed=1;
        for(int i=1;i<=n;i++)
        {
            ed*=3;
        }
        ed--;
        for(int s=0;s<=ed;s++)
        {
            for(int i=1;i<=n;i++)
            {
                dp[s][i]=inf;
            }
        }
        bool ok;
        int ans=inf;
        for(int s=0;s<=ed;s++)
        {
            ok=1;
            for(int i=1;i<=n;i++)
            {
                if(dic[s][i-1])
                {
                    if(s==unit[i-1])
                    {
                        dp[s][i]=0;
                    }
                    else
                    {
                        for(int k=1;k<=n;k++)
                        {
                            if(i!=k&&(dic[s][k-1]))
                            {
                                dp[s][i]=min(dp[s][i],dp[s-unit[i-1]][k]+pho[k][i]);
                            }
                        }
                    }
                }
                else
                {
                    ok=0;
                }
            }
            if(ok)
            {
                for(int i=1;i<=n;i++)
                {
                    ans=min(ans,dp[s][i]);
                }
            }
        }
        if(ans>=inf)
            ans=-1;
        printf("%d\n",ans);
    }
}

 

HDU 3001【状态压缩DP】

标签:

原文地址:http://www.cnblogs.com/tun117/p/4943679.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!