您的位置:首页 > 其它

hdu3001 Travelling(状态压缩dp,三进制)

2016-02-08 01:43 513 查看

hdu3001

分析

这道题一个地点最多可以到两次,所以用三进制,而且判断以及统计结果的时候可以做修改,注意三进制相应的预处理。

题目

http://acm.hdu.edu.cn/showproblem.php?pid=3001

代码

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>

using namespace std;

const int inf=0x3f3f3f3f;

int tri[12] = {0,1,3,9,27,81,243,729,2187,6561,19683,59049};
int n,m;
int dig[59050][11];
int edge[11][11],dp[59050][11];

void init()
{
for(int i=0; i<59050; i++)
{
int temp=i;
for(int j=1; j<=10; j++)
{
dig[i][j]=temp%3;
temp/=3;
if(temp==0) break;
}
}
}

int main()
{
init();
while(scanf("%d %d",&n,&m)!=EOF)
{
memset(edge,inf,sizeof(edge));

int a,b,c;
while(m--)
{
scanf("%d %d %d",&a,&b,&c);
if(c<edge[a][b])
edge[a][b]=edge[b][a]=c;
}

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=1;
for(int i=1;i<=n;i++)
{
if(dig[s][i]==0) visit=0;
if(dig[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 ns=s+tri[j];
dp[ns][j]=min(dp[ns][j],dp[s][i]+edge[i][j]);
}
}
if(visit)
{
for(int j=1;j<=n;j++)
ans=min(ans,dp[s][j]);
}
}
if(ans==inf)
{
printf("-1\n");
continue;
}
printf("%d\n",ans);

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: