2 1 1 2 100 3 2 1 2 40 2 3 50 3 3 1 2 3 1 3 4 2 3 10
100 90 7
#include<stdio.h>
int map[12][12],n,dp[12][60000];//dp[i][state]表示state状态以i点结尾的最小路径
int Min(int a,int b)
{
return a>b?b:a;
}
int toArray(int three[],int sum)
{
int k=0;
for(int i=0;i<n;i++)
{
three[i]=sum%3; sum/=3; if(three[i])k++;
}
return k;//在状态sum中有k个点己经走过
}
int main()
{
int m,a,b,c,in[12],MIN,three[12],k;
in[0]=1;
for(int i=1;i<=10;i++)in[i]=in[i-1]*3; //3的i次方
while(scanf("%d%d",&n,&m)==2)
{
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++)
map[i][j]=-1;
}
while(m--)
{
scanf("%d%d%d",&a,&b,&c); a--; b--;
if(map[a][b]!=-1)//判重
map[a][b]=map[b][a]=Min(map[a][b],c);
else
map[a][b]=map[b][a]=c;
}
MIN=-1;
for(int Go=1;Go<in[n];Go++)//枚举己走的状态Go
{
k=toArray(three,Go);
for(int i=0;i<n;i++)
if(three[i])//状态Go以点i结尾时
{
if(k==1)//只有一个点
dp[i][Go]=0;
if(dp[i][Go]==-1)continue;//状态Go不能以点i为结尾点
if(k==n)//n个点己经走过
{
if(MIN==-1)MIN=dp[i][Go];
else MIN=Min(MIN,dp[i][Go]);
}
for(int j=0;j<n;j++)//找个点j,从i点走到j点,状态tGo以j点结尾
if(i!=j&&three[j]<2&&map[i][j]!=-1)
{
int tGo=Go+in[j];
if(dp[j][tGo]==-1)
dp[j][tGo]=dp[i][Go]+map[i][j];
else
dp[j][tGo]=Min(dp[i][Go]+map[i][j],dp[j][tGo]);
}
}
}
printf("%d\n",MIN);
}
}
hdu3001Travelling (状态压缩DP,三进制),布布扣,bubuko.com
hdu3001Travelling (状态压缩DP,三进制)
原文:http://blog.csdn.net/u010372095/article/details/38474721