您的位置:首页 > 其它

hdu 5418(状态压缩dp+Floyd)

2015-12-28 15:26 295 查看
点击打开链接

解题思路:这道题目和TSP问题很相似,唯一不同的是同一个点可以重复走几次。。。。

这道题目只有16个顶点,所以很容易想到状态压缩dp,dp[i][j]表示到达顶点i时的状态为j的最小花费,那么状态方程也很容易推理出来dp[i][j] = min(dp[k][j-1<<i]+map[i][k]);这里注意,由于每一个点可以到达多次,所以这里的map要先用Floyd算法来处理,否则就会出现用还未更新的状态去更新当前的状态,这样很明显两个状态都无法保证是最优的,第一次WA就是卡在这里,后面看了别人的解题报告,才明白了Floyd算法在这里的重要性。。。

AC:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int inf = 0x3f3f3f3f;
int n,m;
int dp[20][1<<17],map[20][20];

int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int w,u,v,bit;
scanf("%d%d",&n,&m);
memset(map,inf,sizeof(map));
memset(dp,inf,sizeof(dp));
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d",&u,&v,&w);
map[u][v] = min(map[u][v],w);
map[v][u] = map[u][v];
}
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
map[i][j] = min(map[i][j],map[i][k] + map[k][j]);
bit = 1<<n;
dp[1][1] = 0;
for(int j = 1; j < bit; j++)
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
{
if(map[i][k] == inf) continue;
int tmp = 1 << (i-1);
if(j & tmp)
{
if(dp[k][j] != inf)
{
dp[i][j] = min(dp[i][j],dp[k][j] + map[i][k]);
}
if(dp[k][j-tmp] != inf)
{
dp[i][j] = min(dp[i][j],dp[k][j-tmp] + map[i][k]);
}
}
}
printf("%d\n",dp[1][bit-1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp