https://www.luogu.org/problemnew/show/P1433
思路:深搜,不过加剪枝
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
using namespace std;
#define maxn 16
int n;
struct node
{
double x, y;//表示点横纵坐标
bool vis;//标记有没有被搜索过
node():vis(0){};
}Node[maxn];
double a[17][17];//a[i][j]表示第i个点到第j个点的距离
double res = 1<<30;//初始最短路径长度值
void dfs(int num, double nowlength, int now)//分别表示走了多少个点,当前走的长度,当前所在点
{
if(num == n)
{
if(nowlength < res)//更新值
res = nowlength;
return ;
}
if(nowlength > res)//剪枝,没必要搜索下个了
return ;
for(int i = 1; i <= n; i++)
{
if(Node[i].vis == 0)//没有走过的点
{
nowlength += a[now][i];//路径增加
Node[i].vis = 1;//标记放完
num++;//已走的点个数增加
dfs(num, nowlength, i);
//回溯
nowlength -= a[now][i];
Node[i].vis = 0;
num--;
}
}
}
int main()
{
ios::sync_with_stdio (false);
//cin>>n;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
//cin>>Node[i].x;
//cin>>Node[i].y;
scanf("%lf", &Node[i].x);
scanf("%lf", &Node[i].y);
}
Node[0].x = 0;
Node[0].y = 0;
for(int i = 0; i <= n; i++)//预处理第i个点到第j个点的距离
{
for(int j = 0; j <= n; j++)
a[i][j] = sqrt(((Node[i].x - Node[j].x) *( Node[i].x - Node[j].x) + (Node[i].y - Node[j].y)* (Node[i].y - Node[j].y))*1.0);
}
dfs(0, 0, 0);
//cout<<res<<endl;
printf("%.2lf\n", res);
//system("pause");
}