题目大意
给定二维平面上的 n ( n < = 15 ) n(n<=15) n(n<=15)个点,求从 ( 0 , 0 ) (0,0) (0,0)点出发的TSP距离。
做法1(DFS)
分析
首先这道题单纯暴力是肯定会T的,但是注意到这个图是二维平面,所以我们应当利用二维平面点带给我们的一些性质进行优化。那就是:
由近到远的访问,大概会比先访问远处然后回头更优。
那么据此我们就能写出A算法(但是我不会)。于是考虑利用此性质进行预处理,也就是将所有的点按照离原点的欧氏距离大小排序,然后正常跑DFS。由于这样不改变整个搜索树大小,只是可能使我们更早搜到最优解,所以要和卡时结合在一起用。
最终经过实验得出,原本1s会T飞的点,按照预处理过后的顺序搜,只要500ms就能搜到最优解。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
#include <ctime>
using namespace std;
int n;
const int T = CLOCKS_PER_SEC * 0.5;
vector<pair<float, float>> list;
float dist(const pair<float, float> &lhs, const pair<float, float> &rhs)
{
return sqrt(pow(lhs.first - rhs.first, 2) + pow(lhs.second - rhs.second, 2));
}
float ans = 100000000;
#define N 20
bool vis[N];
float dis[N][N];
int t0;
void dfs(int len, int last, float now)
{
int l = last;
float d = now;
for (int i = 1; i <= n; i++)
if (!vis[i])
{
now += dis[last][i];
last = i;
vis[i] = true;
if (len + 1 == n)
{
if (now < ans)
ans = now;
if (clock() - t0 > T)
{
printf("%.2lf", ans);
exit(0);
}
vis[i] = false;
return;
}
else if (now < ans