搜索这个东西看起来简单
但实际操作时,却异常复杂
复杂就复杂在算法的优化上
深搜基操——诶
展示下吧
if判断—>for循环枚举各个方向 ->对目标操作->递归->回溯
额
优化有两种
1°:
记忆化搜索:
dp题数字三角形,其中一种方法是记忆化搜索:
需要开额外空间来存储
额
就是以空间换时间
这个题就不贴代码了
2°:
剪枝:
因为剪枝比较复杂,我就举个例子说说
ROADS(算法基础与在线实践&&洛谷):
剪枝有两种
一种是可行性剪枝
及早发现正在探索的路走不到终点
因而不再走下去,这种剪枝属于比较基础的
另一种是最优性剪枝
走到某节点时发现此时付出的代价已经超过前面记录的
故不在走下去
看起来都挺简单
其实确实不复杂
但最优性剪枝的分支——
预见性最优性剪枝
处处最优剪枝
就比较复杂了
预见性:走到某节点确实不超过范围,但预见未来必定会超过范围
故不在走下去
处处最优:记下起点到目前每一个点最优路径的代价
篇幅有限,就举例处处最优
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<vector>
5 using namespace std;
6 struct road{
7 int d;
8 int l;
9 int cost;
10 };
11 vector<vector<road> > vec(110);
12 int now_len;
13 int now_cost;
14 int opt_len=1<<30;
15 int costl;
16 int totcost;
17 int N,R;
18 bool visit[110];
19 int d_cost_len[110][10100];
20 void search(int);
21 int main(void)
22 {
23 cin>>costl>>N>>R;
24 int a;
25 road r;
26 for(int i=0;i<R;++i)
27 {
28 cin>>a>>r.d >>r.l >>r.cost ;
29 if(a!=r.d ) vec[a].push_back(r);
30 }
31 for(int i=0;i<110;++i)
32 {
33 for(int j=0;j<10100;++j)
34 {
35 d_cost_len[i][j]=1<<30;
36 }
37 }
38 memset(visit,0,sizeof(visit));
39 visit[1]=1;
40 search(1);
41 if(opt_len<(1<<30)) cout<<opt_len;
42 else cout<<opt_len;
43 }
44 void search(int c){
45 if(c==N) {
46 opt_len=min(opt_len,now_len);
47
48 return;
49 }
50 for(int i=0;i<vec[c].size();++i)
51 {
52 int u=vec[c][i].d;
53 if(!visit[u]){
54 if(now_len+vec[c][i].l>opt_len||now_len+vec[c][i].l>d_cost_len[u][now_cost+vec[c][i].cost]) continue;
55 if(now_cost+vec[c][i].cost>costl) continue;
56 now_len+=vec[c][i].l;
57 now_cost+=vec[c][i].cost;
58 visit[u]=1;
59 d_cost_len[u][now_cost]=now_len;
60 search(u);
61 now_len-=vec[c][i].l;
62 now_cost-=vec[c][i].cost;
63 visit[u]=0;
64 }
65 }
66 }
11行:vec是动态二位数组
55行:可行性剪枝,钱不够就退回去
54行:在路费与终点都一定的情况下,优先路程最短的,检查是否满足处处最优性
56-63行:回溯
搜索是一种重要的思想
在以后图的遍历时
也会经常被使用
-end-
来源:https://www.cnblogs.com/-Iris-/p/12362369.html