深搜
深搜,顾名思义就是往深了搜。每次,只要你发现下一个点可以走,你马上走上去 就行啦!!就这样不断递归,直到遇到你的边界条件,撞到了南墙,你再也走不下去了,哼哼,我回头退回去!!
可以跟大家看下样例::(自己去题面看图) 样例是从1出发,先走2,然后走5,发现走不下去,退回来。 站在2这里,我们又往6走,发现又走不下去了,退回2.此时2没有点可走,退回1,去往3。 在3点,我们前往7,然后再往8,无路可走,退回7-》3——》1.最后走4。
广搜和深搜略有不同。
广搜就是先站在目前这个点,将周围扫描一遍,如果可以走,我就矜持一点,不马上走你,而是将你存入队列里面。等到队列里前面的点都搜完了,才轮到它上。这里靠语言描述或许没有那么好,还是看代码比较舒服。
完整板子代码(注意排序函数,十分有用):
#include<bits/stdc++.h> using namespace std; #define N 900010 #define orz 0 //数组注意开大点,不然很容易WA或者RE inline int read(){ int x = 0,s = 1; char c = getchar(); while(c < ‘0‘ || c > ‘9‘){ if(c == ‘-‘)s = -1; c = getchar(); } while(c >= ‘0‘ && c <= ‘9‘){ x = (x << 1) + (x << 3) + (c ^ ‘0‘); c = getchar(); } return x * s; } struct hhh{ int x,y; } b[N]; int n,m; int f[N]; struct node{ int u,v,next; } t[N]; bool vis1[N]; void dfs(int now){ for(int i = f[now];i;i = t[i].next){ int v = t[i].v; if(!vis1[v]){ printf("%d ",v); vis1[v] = 1; dfs(v); } } } queue <int> q; bool vis2[N];//其实把上面那个vis1清空也可以,不过这样省清空时间。 void bfs(){//广搜模板直接打上去 q.push(1); while(!q.empty()){ int now = q.front(); q.pop(); printf("%d ",now); for(int i = f[now];i;i = t[i].next){ int v = t[i].v; if(!vis2[v]){ vis2[v] = 1; q.push(v); //和深搜不同,广搜发现可以用的点是存入队列,而不是直接跑过去 } } } } bool cmp(hhh a,hhh b){//一个十分特殊但是很有用的排序cmp函数。 return a.y > b.y || (a.y == b.y && a.x > b.x);//勤加思考,大家自行理解一下 } int cnt1 = 0;//经典链表存图 void add(int u,int v){ cnt1++; t[cnt1].u = u; t[cnt1].v = v; t[cnt1].next = f[u]; f[u] = cnt1; return; } int main(){ //freopen("hh.txt","r",stdin); n = read(),m = read(); for(int i = 1;i <= m; i++){ b[i].x = read(),b[i].y = read(); }//先用另外一个结构体将每个点的信息排好序,再进行建图. sort(b + 1,b + m + 1,cmp); for(int i = 1;i <= m; i++) add(b[i].x,b[i].y); printf("1 "); vis1[1] = 1; dfs(1); printf("\n"); vis2[1] = 1; bfs(); return orz; }
原文地址:https://www.cnblogs.com/wondering-world/p/12634479.html
时间: 2024-10-09 23:55:55