搜索这个东西看起来简单
但实际操作时,却异常复杂
复杂就复杂在算法的优化上
深搜基操——诶
展示下吧
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-