原题链接
题目大意
有
n
n
n个村庄,每个村庄之间都有路,给出他们的长度,求出从
1
1
1号村庄开始出发,到每个村庄各一次,再回到
1
1
1号村庄的最短路径。
S
a
m
p
l
e
\mathbf{Sample}
Sample
I
n
p
u
t
\mathbf{Input}
Input
3// 村庄数量
0 2 1 // 村庄 1 到各村的路程
1 0 2
2 1 0
S a m p l e \mathbf{Sample} Sample O u t p u t \mathbf{Output} Output
3
解题思路
用裸的顺搜肯定是愉快
T
L
E
{\color{darkblue}TLE}
TLE的,我们需要剪枝。
剪枝一:最优性剪枝
如果当前已经求出来的一种可行方案的价值已经
≤
\le
≤当前的价值,那么他无论以后怎么走都只会更差
,倒不如直接不走了。即:
if(ans<=当前价值) return;
剪枝二:可行性剪枝
这个剪枝就有点难想了,如果说以后要走的路都是最小的1
也
≥
a
n
s
\ge ans
≥ans,那么也干脆不走了,毕竟无论怎么走最后总是
≥
\ge
≥最优值。即:
设已经走了k个城市
if(n-k+当前价值>=ans) return;
上代码
#include<iostream>
using namespace std;
int n,res=0x7fffffff;
int a[50][50];
bool vis[50];
void dfs(int dep,int k,int sum)
{
if(sum>=res) return;
if(dep==n)
{
res=std::min(res,sum+a[k][1]);
return;
}
if(sum+(n-dep+1)>=res) return;
for(int i=1; i<=n; i++)
if(!vis[i])
{
vis[i]=true;
dfs(dep+1,i,sum+a[k][i]);
vis[i]=false;
}
}
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
cin>>a[i][j];
vis[1]=true;
dfs(1,1,0);
cout<<res<<endl;
return 0;
}
完美切题 ∼ \sim ∼