洛谷P1433 吃奶酪——DFS,最优化剪枝

题目:https://www.luogu.org/problemnew/show/P1433

思路:

1、以(0,0)点为起点,进行深搜,相当于进行全排列。

2、最优化剪枝,如果得到的当前距离比已知的最小距离大了,跳出当前层的搜索,这样可以大大节省时间。

if(sum>minn)return;

3、不要与欧拉路、欧拉回路、哈密尔顿环混淆。

4、因为最多15个点,没有必要引入记忆化。

AC代码如下:

/*为保证精度,应该采用double,不能采用float,否则卡三个点*/ 
#include
#include
#include
using namespace std;
int n;
double x[16]={0},y[16]={0};
double minn=1e9,sum=0;
bool vis[16];

double dis(int a,int b){
	return sqrt( (x[a]-x[b])*(x[a]-x[b]) + (y[a]-y[b])*(y[a]-y[b]) );
}

void dfs(int cns,int x){
	if(cns==n){
		minn=min(minn,sum);
		return;
	};
	if(sum>minn)return;/*最优化剪枝,否则TLE*/ 
	for(int i=1;i<=n;i++)
		if(!vis[i]){
			vis[i]=1;
			sum+=dis(x,i);
			dfs(cns+1,i);
			/*回溯*/ 
			vis[i]=0;
			sum-=dis(x,i);
		}
}

int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>x[i]>>y[i];
	vis[0]=1;
	dfs(0,0);
	
	printf("%.2f\n",minn);
}

 

你可能感兴趣的:(洛谷P1433 吃奶酪——DFS,最优化剪枝)