不得不说我图的这边学的很用心了,但依旧还是有很多带题不会
首先我们来看一下这两种的区别,我们应该在什么题里用?这是我自己总结的一些
https://blog.csdn.net/weixin_44067773/article/details/87471377
那我们再来看一下二者的定义,他们是如何运行的
BFS:就是一直往深处走,走的地方标记一下然后递归回退到其他没走的点,在走,在标记,知道结束
DFS:先找离跟最近的节点,然后把他们压入队列,再把他们当作根,再找离他们最近的结点,依次进行
那么如何写呢:
BFS:http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2717/pid/2107
#include<stdio.h>
#include<string.h>
int map[105][105];//图
int vis[105];//标记该点是否已经走到
int k;
void dfs(int i)
{
vis[i]=1;
if(i==0)
printf("%d",i);
else
printf(" %d",i);
int j;
for(j=0;j<k;j++)
{
if(!vis[j]&&map[i][j])//这一步循环从0开始,先把0的vis=1,然后在往后加(此时0不符合if判断)然后在换成1,1符合再标记输出1,然后再从1(2,3,由于1没有到达2和3的)然后再往下循环
dfs(j);//i->j没有走过dfs
}
}
int main()
{
int u,v;
int m,n;
while(scanf("%d",&n)!=EOF)
{
while(n--)
{
memset(map,0,sizeof(map));
memset(vis,0,sizeof(vis));
scanf("%d %d",&k,&m);
while(m--)
{
scanf("%d %d",&u,&v);
map[u][v]=1;
map[v][u]=1;//双向图,便于回撤和前进
}//如果vis为假执行(vis所代表的数没被扫过)
dfs(0);
printf("\n");
}
}
return 0;
}
DFS:邻接矩阵实现法:
http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2717/pid/2141
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int tu[500][500];
int vis[500];
int ans[500];
int k,num;
void bfs(int t)
{
int v,i;
queue<int>Q;
ans[num++]=t;
vis[t]=1;
Q.push(t);
while(!Q.empty())
{
v=Q.front();
Q.pop();
for(i=0;i<=k-1;i++)
{
if(!vis[i]&&tu[v][i])
{
vis[i]=1;
ans[num++]=i;
Q.push(i);
}
}
}
}
int main()
{
int n,m,t,u,v,i;
scanf("%d",&n);
while(n--)
{
memset(tu,0,sizeof(tu));
memset(vis,0,sizeof(vis));
scanf("%d %d %d",&k,&m,&t);
for(i=0;i<=m-1;i++)
{
scanf("%d %d",&u,&v);
tu[u][v]=tu[v][u]=1;
}
bfs(t);
for(i=0;i<=num-1;i++)
{
if(i==num-1)
printf("%d\n",ans[i]);
else
printf("%d ",ans[i]);
}
}
return 0;
}
人工debug:我们先把0(开头)推进去,找到离0最近的n个结点,在标记,在找离这n个结点最近的n2个结点,标记,再把他们推进去
邻接表可以想象成把数组竖起来然后每个后面都接上相应的结点
下面是邻接表法:适用于数据量较大的题目:
http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2717/pid/2142
参考代码: