您的位置:首页 > 其它

hdu 3001(状态压缩dp)

2013-08-16 10:25 441 查看
点击打开链接

题意:

有n个城市,m条路,每个城市最多走两次,求走完全部城市的最小路程。。。

因为没个城市最多走两次,所以要用3进制,求出1<<10的所有状态,并且此状态中每个城市走的次数。

状态方程dp[i+t3[k]][k]=max(dp[i][j]+map[j][k]);

dp[i][j]表示在状态i时走到j的最短路程。。。。

#include"stdio.h"
#include"string.h"
#define N 11
#define inf 0x1f1f1f1f
int state[60000]
;
int dp[60000]
;
int map

;
int t3
;
int top,n;
void init()
{
int i,j;
top=0;
for(i=0;i<60000;i++)
{
int t=i;
for(j=0;j<10;j++)
{
state[i][j]=t%3;
t/=3;
}
}
t3[0]=1;
for(i=1;i<N;i++)
t3[i]=t3[i-1]*3;
}
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
int m;
int i,j,k;
init();
while(scanf("%d%d",&n,&m)!=-1)
{
memset(map,inf,sizeof(map));
memset(dp,inf,sizeof(dp));
while(m--)
{
scanf("%d%d%d",&i,&j,&k);
i--;j--;
if(map[i][j]>k)map[i][j]=map[j][i]=k;
}
for(i=0;i<n;i++)dp[t3[i]][i]=0;
int ans=inf;
for(i=0;i<t3
;i++)
{
int f=1;
for(j=0;j<n;j++)
{
if(state[i][j]==0)f=0;
if(dp[i][j]==inf)continue;
for(k=0;k<n;k++)
{
if(j==k)continue;
if(state[i][k]>=2)continue;
if(map[j][k]==inf)continue;
dp[i+t3[k]][k]=min(dp[i][j]+map[j][k],dp[i+t3[k]][k]);
}
}
if(f==1)
{
for(j=0;j<n;j++)
ans=min(ans,dp[i][j]);
}
}
if(ans>=inf)ans=-1;
printf("%d\n",ans);
}
return 0;
}

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