洛谷P1433 吃奶酪【dfs】【剪枝】

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

题意

给定n个坐标,要求从(0,0)开始走遍所有点,最少经过的路程。

思路:

刚开始想像数字三角形一样适用next_permutation,枚举坐标的顺序,一旦出现距离比当前最优解要差时就sort剪枝。

这里sort的起始和结束要注意一下,和那道题不一样。开始应该是i+1

但是还是有一个点会TLE。毕竟sort了一下还是会慢一点...?

所以还是老老实实dfs吧。道理都是一样的,搜索走的下标排列,一旦出现比最优解差就直接回溯。

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<map>
 4 #include<set>
 5 #include<iostream>
 6 #include<cstring>
 7 #include<algorithm>
 8 #include<vector>
 9 #include<cmath> 
10 #include<queue>
11 
12 #define inf 0x7f7f7f7f
13 using namespace std;
14 typedef long long LL;
15 typedef pair<int, int> pr;
16 
17 int n;
18 struct node{
19     double x, y;
20 }pos[20];
21 int per[20];
22 double d[20][20];
23 
24 double dist(node a, node b)
25 {
26     return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
27 }
28 
29 bool cmp(int a, int b)
30 {
31     return a > b;
32 }
33 
34 bool vis[20];
35 double ans = inf;
36 void dfs(int pre, int m, double res)
37 {
38     if(res > ans)return;
39     if(m == n){
40         ans = min(ans, res);
41         return;
42     }
43     for(int i = 1; i <= n; i++){
44         if(!vis[i]){
45             vis[i] = true;
46             dfs(i, m + 1, res + d[pre][i]);
47             vis[i] = false;
48         }
49     }
50     return;
51 } 
52 
53 int main()
54 {
55     scanf("%d", &n);
56     pos[0].x = 0;
57     pos[0].y = 0;
58 //    node st;
59 //    st.x = 0;st.y = 0;
60     for(int i = 1; i <= n; i++){
61         scanf("%lf%lf", &pos[i].x, &pos[i].y);
62         per[i] = i;
63     }
64     for(int i = 0; i <= n; i++){
65         for(int j = i + 1; j <= n; j++){
66             d[i][j] = d[j][i] = dist(pos[i], pos[j]);
67         }
68     }
69     
70     dfs(0, 0, 0);
71     
72     
73 //    double ans = inf;
74 //    do{
75 //        double tmp = 0;
76 //        //double tmp = dist(st, pos[per[1]]);
77 //        for(int i = 1; i < n; i++){
78 //            tmp += d[per[i]][per[i + 1]];
79 //            //tmp += dist(pos[per[i]], pos[per[i + 1]]);
80 //            if(tmp > ans){
81 //                sort(per + i + 1, per + 1 + n, cmp);
82 //                break;
83 //            }
84 //        } 
85 ////        for(int i = 1; i <= n; i++){
86 ////                cout<<per[i]<<" ";
87 ////            }
88 ////            cout<<endl;
89 ////        if(tmp < ans){
90 ////            
91 ////        }
92 //        //tmp += dist(st, pos[per[1]]); 
93 //        tmp += d[0][per[1]];
94 //        ans = min(ans, tmp);
95 //    }while(next_permutation(per + 1, per + 1 + n));
96     
97     printf("%.2lf\n", ans);
98     return 0;
99 }

猜你喜欢

转载自www.cnblogs.com/wyboooo/p/10356706.html
今日推荐