题目描述 Description
某乡有n个村庄(1<n<=15),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<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考虑!
分类标签 Tags
#include<iostream> #include<cstdio> #include<cstring> #include<ctime> using namespace std; int n,a[20][20],ans=0xfffffff,f[20],b[20][20]; void dfs(int now,int sum,int dis) { if(dis+b[now][1]>ans)return; if(now==1&&sum==n) { if(ans>dis) ans=dis; return ; } for(int i=1;i<=n;i++) { if(i==1&&sum<n-1)continue; if(i!=now&&!f[i]) { //if(dis+a[now][i]>ans)break;//超强剪枝 然而并不对,数据渣渣才能过 下面带数据 f[i]=1; dfs(i,sum+1,dis+a[now][i]); f[i]=0; } } } int main() { int i,j,k; scanf("%d",&n); for(i=1;i<=n;i++) for(j=1;j<=n;j++) { scanf("%d",&a[i][j]); b[i][j]=a[i][j]; } for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) b[i][j]=min(b[i][j],b[i][k]+b[k][j]); dfs(1,0,0); printf("%d ",ans); return 0; } /* 14 0 8 9 3 4 5 6 5 6 2 3 9 1 2 2 0 4 5 6 9 3 6 6 5 8 9 2 1 1 2 0 3 4 5 6 7 7 4 3 2 3 2 4 2 3 0 4 5 6 2 8 7 3 4 3 3 3 2 3 4 0 5 6 7 7 6 8 5 1 1 8 2 3 4 5 0 6 2 1 4 3 5 2 1 7 2 3 4 5 6 0 1 2 8 9 6 4 5 9 2 2 1 1 2 2 0 1 5 3 6 3 2 2 1 1 2 2 1 1 2 0 5 6 8 1 5 3 5 8 9 4 3 6 5 1 0 5 6 1 4 2 3 5 6 9 6 8 9 4 2 0 5 2 5 5 6 8 9 6 9 8 7 5 6 3 0 3 6 5 6 8 9 7 4 3 1 2 3 2 3 0 2 6 5 3 2 4 8 5 2 3 2 2 3 4 0 25 */ /* 6 0 2 1 20 20 20 1 0 2 20 20 20 20 20 0 2 1 20 20 20 20 0 2 1 20 20 20 1 0 2 2 1 20 20 2 0 6 */