基于vector建图的深搜和广搜
作者:互联网
题目传送门
洛谷 P5318
vector建图+深搜+广搜
分析:先用vector建个图,也可用邻接表,建图之后要先排序,题目要求先从小编号的开始,然后分别进行dfs和bfs,时隔多日,写dfs又开始懵了,犯了老毛病,不知道函数怎么返回了
下面分析一下bfs和dfs的过程,首先是dfs,先传了1到dfs函数中,x为1,标记1走过了,找1的出边为2,以2为起点找2的出边,找到了5,以5为起点找5的出边,发现5没有出边,返回主调函数,
也就是dfs(2),进入循环,发现6没有走过,标记6,以6为起点找6的出边,发现6没有出边了,所以返回dfs(2),以2为起点的出边全都被标记了,这时候继续返回主调函数,返回dfs(1),以1为起点,找没有被标记过的出边,找到了3,标记3,以3为起点标记3的出边,然后依次类推即可
再说说bfs的过程,bfs是维护了一个队列,先传了一个1到主调函数中,记录队首元素1,输出队首元素1 ,弹出队首元素1,再将以1为起点的所有出边都入队列,此时队列里就是1 2 3 4,并且标记,此时队首元素变成了2,记录队首元素2,输出队首元素2,弹出队首元素2,以2为起点的所有出边都入队列,5,6入队列,此时队列里就是3 4 5 6,队首元素变成了3,记录队首元素3,弹出队首元素3,以3为起点的出边的入队列7,8入队列,此时队列里就是4 5 6 7 8,队首元素变成了4,记录队首元素,弹出队首元素4,以4为起点的出边入队列,7已经入过了(有被标记),所以是8入队列,队首元素变成5,弹出队首元素此时队列里就是 6 7 8,然后q不为空,一直弹出队首元素(不会再进for循环了,因为剩下的元素都没有出边了),最后的顺序就是1 2 3 4 5 6 7 8
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
int n, m;
int u, v;
const int maxn = 100000 + 10;
int vis[maxn];
vector<int> g[maxn];
queue<int> q;
void dfs(int x, int y) {
vis[x] = 1; //标记这个点已经走过
cout << x << " ";
if (y == n)
return;
for (int i = 0; i < g[x].size(); i++) {
if (vis[g[x][i]] == 0)
dfs(g[x][i], y + 1);
}
}
void bfs(int x) {
vis[x] = 1;
q.push(x);
while (!q.empty()) {
int h= q.front();
cout << h << " ";
q.pop();
for (int i = 0; i < g[h].size(); i++) {
if (vis[g[h][i]] == 0) {
q.push(g[h][i]);
vis[g[h][i]] = 1;
}
}
}
}
int main() {
cin >> n >> m;
for (int i = 0; i < m; i++) {
cin >> u >> v;
g[u].push_back(v);//建图
}
for (int i = 1; i <= n; i++) {
sort(g[i].begin(), g[i].end()); //根据题意排序
}
dfs(1, 0);
memset(vis, 0, sizeof(vis));
cout << endl;
bfs(1);
}
今天竟然dfs都搞不清了。。
菜鸡还是要多多努力吧!
标签:int,队首,元素,dfs,队列,建图,vector,搜和广,出边 来源: https://blog.csdn.net/qq_51817638/article/details/115428214