hdu3001(3进制状态压缩dp)

来源:互联网 发布:ntfs for mac 10.11.6 编辑:程序博客网 时间:2024/06/04 20:06

和正常的没什么不同,就是一个点可以到两次,所以就用三进制来压

并且,TSP的问题的状态表示都是dp【i】【k】,经过的点的集合表示为i,且现在走到k时的最短距离

//同时,注意初始化最大值之类的,例如表示距离的,如果没有说就是最大值

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>using namespace std;int n,a[12][12],m,f[531445][12];int main(){while (scanf("%d%d",&n,&m)!=EOF){memset(a,0x3f3f3f3f,sizeof(a));int x,y,z;while (m--){scanf("%d%d%d",&x,&y,&z);if (a[x][y]==0x3f3f3f3f)a[x][y]=a[y][x]=z;else a[x][y]=a[y][x]=min(a[x][y],z);}memset(f,0x3f3f3f3f,sizeof(f));int p=1;for (int i=1;i<=n;i++) {f[p][i]=0;p*=3;}p--;for (int pp=1;pp<=p;pp++){int b[20]={0},l=pp;while (l) b[++b[0]]=l%3,l/=3;for (int i=1;i<=n;i++) if (b[i]){int c[20];memcpy(c,b,sizeof(c));c[i]--;int k=0;for (int j=n;j>0;j--) k=k*3+c[j];for (int j=1;j<=n;j++) if (i!=j)f[pp][i]=min(f[pp][i],f[k][j]+a[j][i]);}}int ans=0x3f3f3f3f;for (int i=1;i<=p;i++){int b[20]={0},l=i,j;while (l) b[++b[0]]=l%3,l/=3;for (j=1;j<=n;j++) if (b[j]==0) break;if (j<=n) continue;for (j=1;j<=n;j++) ans=min(ans,f[i][j]); }if (ans!=0x3f3f3f3f) printf("%d\n",ans);else printf("-1\n"); }return 0;}


0 0
原创粉丝点击