两种搜索总结

搜索时所有的点都只遍历一次,所以不管是bfs还是dfs我们都需要开个bool数组或int数组来记录是否被搜过(一般搜索点用dfs的话用bool数组,用bfs搜索图的话一般求距离数组用int数组初始化为-1)

存图:用邻接表,单链表中e[n]存数 ne[n]存下一个数的下标 head=-1头结点(注意:在图中用邻接表存的话,要开e[2*n],ne[2*n],因为每个点有两条边,在之前的题中pair<int,int> 存坐标时也是要建立q[n*n]个)

void add(int a,int b){//把a和b连起来,如果是无向边的话需要add(a,b)和add(b,a)
	e[idx]=b;
	ne[idx]=h[a];
	h[a]=idx;
	idx++;
}

邻接表的头节点是一个数组h[n]

遍历单链表的话

for(int i =head;i!=-1;i=ne[i]){//i相当于下标
	cout<<e[i];
}

遍历图的邻接表的话,比如遍历编号为n的点,吧head换为h[n]就可以了

for(int i =h[n];i!=-1;i=ne[i]){
	cout<<e[i];
}

深度优先遍历图:当遍历到编号为u的节点时,修改u的状态为true表示已经走过,然后遍历与u相连的点,如果没走过就遍历它(注意:与之前的n皇后不一样,每个点都走一次所以出来时不需要恢复状态)

void dfs(int u){
	st[u]=true;
	for(int i=h[u];i!=-1;i=ne[i]){
		int j=e[i];//j是i这个下标存的点的编号
		if(!st[j])dfs(j);//如果没被走过,就遍历它
	}
}

例题:数的重心

宽度优先遍历图有框架:

刚开始时初始化队列,队头先插入初始点,初始点的d数组值为0;

一般都求距离,建立一个距离数组为d[n],初始化为-1,判断是否被遍历一般看d[x]是否为-1.

先把起始点插入队列,while队列不空,取出队头元素t,遍历队头t所有的邻点x,如果x未被遍历,那么就把x入队,更新一下x的距离d[x]=d[t]+1

int bfs(){
	memset(d,-1,sizeof(d));//初始化距离为-1
	q[0]=1;//取初始点存入队列
	d[1]=0;//第一个点的距离记作0
	int hh=0,tt=0;//初始化头和尾
	while(hh<=tt){
		int t=q[hh++];//取头节点
		for(int i=h[t];i!=-1;i=ne[i]){
			int j=e[i];
			if(d[j]==-1){//如果这个点没有被走过
				q[++tt]=j;
				d[j]=d[t]+1;
			}
		}
	}
	return d[n];
}

例题:图中点的层次

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值