题目描述 Description
某乡有n个村庄(n<=15),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(s<1000)是已知的,且A村到B村与B村到A村的路大多不同。为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为1,他不知道选择什么样的路线才能使所走的路程最短。请你帮他选择一条最短的路。Input Description
村庄数n和各村之间的路程(均是整数)
输出描述 Output Description
最短的路程
样例输入 Sample Input
3
0 2 1
1 0 2
2 1 0
样例输出 Sample Output
3
数据范围及提示 Data Size & Hint
本题可用最短路思想、搜索来解决,但是可能无法通过一组极限数据(且效率较低)。建议按树状DP考虑!
分析:
不会的树上的dp啊,搜索又好像过不了,只能打状丫了
定义状态:f[i][j] i点j时的情况
状丫中的基础题
Code:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<queue>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int INF=0x3f3f3f,Maxm=(1<<15)+10,Maxn=15+10;
int n,ans=INF,map[Maxn][Maxn],f[Maxn][Maxm];
int main(){
scanf("%d",&n);
fo(i,1,n)
fo(j,1,n) scanf("%d",&map[i][j]);
memset(f,63,sizeof(f));
f[1][1]=0;
fo(i,1,(1<<n)-1)
{
fo(j,1,n)
{
if(i&(1<<(j-1)))
{
fo(k,1,n)
{
if(!(i&(1<<(k-1))))
{
//此时j点访问过而k点并没有访问过
//所以要得到访问过k点就等于k到j的值
f[k][i|(1<<(k-1))]=min(f[k][i|(1<<(k-1))],f[j][i]+map[j][k]);
}
}
}
}
}
fo(i,1,n)
ans=min(ans,f[i][(1<<(n))-1]+map[i][1]);
printf("%d",ans);
return 0;
}