hack数据组的第一个数据有重复点,简单的解决方法是去重。照搬离散化处理的前置操作(笑
#include<bits/stdc++.h>
using namespace std;
int n;
double l[100][100];//存两点之间的距离
double a[100][2];
double hist[(1 << 15) + 5][16];//在已经走过一些点时走到某个点的路程最小值
double ans=INT_MAX;
double length(double a1, double b1, double a2, double b2)
{
//cout << a1 - a2 << " " << b1 - b2 << endl;
return sqrt((a1 - a2) * (a1 - a2) + (b1 - b2) * (b1 - b2));
}
bool done[100];//标记这个点是否走过
//x表示当前走了多少个点 p表示当前位置的二进制序号 ansnow表示当前的总路程 i表示当前点的序号
void dfs(int x,int p,double ansnow,int i)
{
if (x >= n + 1)//已经走完了
{
if (ansnow < ans)
ans = ansnow;
return;
}
for(int j=1;j<=n;j++)
if (!done[j])//如果这个点没被走过
{
int newp = p + (1 << (j - 1));//p+2*n^(j-1),显然同一个p值只能是一种走法
double newans = ansnow + l[j][i];
if (hist[newp][j])//首先这个点要被走过
if (hist[newp][j] < newans)//而且有更短的走法
continue;//剪枝
done[j] = true;
hist[newp][j] = newans;
dfs(x + 1, newp, newans, j);
done[j] = false;//回溯
}
}
int main()
{
cin >> n;
int i, j;
a[0][0] = 0;
a[0][1] = 0;//起点
vector<pair<double, double>>A;//去重的部分:有一个点有重复数据
for (i = 1;i <= n;i++)
{
double x, y;
cin >> x >> y;
A.push_back(pair<double, double>(x, y));
}
sort(A.begin(), A.end());
A.erase(unique(A.begin(), A.end()), A.end());
n = A.size();
for (i = 0;i < n;i++)
{
a[i + 1][0] = A[i].first;
a[i + 1][1] = A[i].second;
}
for (i = 0;i <= n;i++)
{
for (j = i + 1;j <= n;j++)
{
double x = length(a[i][0], a[i][1], a[j][0], a[j][1]);
l[i][j] = x;
l[j][i] = x;
//cout << x << endl;
}
}
dfs(1, 0, 0, 0);
cout << fixed << setprecision(2) << ans << endl;
return 0;
}