DFS
基本思路
就是将经过的顶点设置为已访问,在下次递归遇到这个顶点就无视,直到整个图顶点都被标记已访问。
伪代码思路
DFS(u){//访问顶点u
vis[u] = true; //设置u点已访问
for(从u出发能到达的所有顶点v)
if vis[u] == false //如果v未被访问
DFS(v); //递归访问v
}
DFSTrave(G){ //遍历图G
for(G的所有顶点) //防止非连通图的情况,有多个连通块
if vis[u] == false //如果u未被访问
DFS(u); //访问u所在连通块
邻接矩阵版
#include <bits/stdc++.h>
using namespace std;
const int MAXV = 1000;
const int INF = 10000000; //上限值
int n, G[MAXV][MAXV]; //n个顶点,MAXV最大顶点数
bool vis[MAXV] = {false};
void DFS(int u, int depth)
{
vis[u]=true;
// 对u的操作可以在这进行
for (int v = 0; v < n; v++)
{
if (vis[u] == false && G[u][v] != INF)
DFS(v, depth + 1);
}
}
void DFSTrave() //遍历图G
{
for (int u = 0; u < n; u++)
{
if (vis[u] == false)
DFS(u, 1); // 访问u和u所在的连通块,1表示初始为第一层
}
}
邻接表版
#include <bits/stdc++.h>
using namespace std;
const int MAXV = 1000;
const int INF = 10000000; //上限值
vector<int> Adj[MAXV];
int n;
bool vis[MAXV] = {false};
void DFS(int u, int depth)
{
vis[u] = true;
// 对u的操作可以在这进行
for (int i = 0; i < Adj[u].size(); i++)
{
int v = Adj[u][i];
if (vis[v] == false) //如果未被访问,就访问该点的下一层
DFS(v, depth + 1);
}
}
void DFSTrave() //遍历图G
{
for (int u = 0; u < n; u++)
{
if (vis[u] == false)
DFS(u, 1); // 访问u和u所在的连通块,1表示初始为第一层
}
}
BFS
基本思路
建立一个队列,并把初始顶点加入队列,此后每次都取出队首顶点进行访问,并把从该点出发可以到达的未加入过队列的(不是未访问)的顶点全加入队列,直到队列为空。
伪代码思路
BFS(u){
queue q;
将u入队
inq[u] =true;
while(q非空){
取出q的队首元素进行访问;
for(从u出发可达的所有顶点v)
if(inq[v]==false)
将v入队;
inq[v]=true;
}
}
}
BFSTrave(G){
for(G的所有顶点u)
if(inq[u]==false){
BFS(u);
}
}
邻接矩阵版
#include <bits/stdc++.h>
using namespace std;
const int MAXV = 1000;
const int INF = 10000000; //上限值
int n,G[MAXV][MAXV];
bool inq[MAXV] = {false};
void BFS(int u)
{
queue<int> q;
q.push(u);
inq[u]=true;
while (!q.empty())
{
int u=q.front();
q.pop();
for(int v=0;v<n;v++)
{
if(inq[v]==false&&G[u][v]!=INF)
{
q.push(v);
inq[v]=true;
}
}
}
}
void BFSTrave() //遍历图G
{
for (int u = 0; u < n; u++)
{
if (inq[u] == false)//如果u未曾加入过队列
BFS(u); // 访问u和u所在的连通块,1表示初始为第一层
}
}
邻接表版
#include <bits/stdc++.h>
using namespace std;
const int MAXV = 1000;
const int INF = 10000000; //上限值
vector<int> Adj[MAXV];
int n;
bool inq[MAXV] = {false};
void BFS(int u)
{
queue<int> q;
q.push(u);
inq[u]=true;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<Adj[u].size();i++)
{
int v=Adj[u][i];
if(inq[v]==false)
{
q.push(v);
inq[v]=true;
}
}
}
}
void DFSTrave() //遍历图G
{
for (int u = 0; u < n; u++)
{
if (inq[u] == false)
{
BFS(u); // 访问u和u所在的连通块,1表示初始为第一层
}
}
}
若要输出连通块所有其他顶点层号
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int v;//顶点编号
int layer;//顶点层号
};
const int MAXV = 1000;
const int INF = 10000000; //上限值
vector<Node> Adj[MAXV];
int n;
bool inq[MAXV] = {false};
void BFS(int s)
{
queue<Node> q;
Node start;
start.v=s;
start.layer=0;
q.push(start);
inq[start.v]=true;
while(!q.empty())
{
Node topNode=q.front();
q.pop();
int u=topNode.v;
for(int i=0;i<Adj[u].size();i++)
{
Node next=Adj[u][i];
next.layer=topNode.layer+1;
if(inq[next.v]==false)
{
q.push(next);
inq[next.v]=true;
}
}
}
}
void DFSTrave() //遍历图G
{
for (int u = 0; u < n; u++)
{
if (inq[u] == false)
{
BFS(u); // 访问u和u所在的连通块,1表示初始为第一层
}
}
}