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