文章目录
-
- 图的存储
-
- DFS 寻找所有路径
-
- BFS 寻找所有路径
-
- 写在后面
图的存储
理论知识
- 图的存储主要有 2 种方式
- 邻接表
- 邻接矩阵
邻接矩阵不适合存储稀疏图,本文使用邻接表来存储图
- 邻接表
- 邻接表用多个链表来表示图,每个链表的头节点表示图中节点,而头结点指向的节点是图中该节点所指向的所有节点
- 示例
- 节点
1
指向的节点有 2、3
,因此以 1
为头结点的链表,头结点指向的节点是2、3
需要说明的是,如果没有特殊规定,邻接表的顺序是任意的,例如图中节点1
的链表也可以是1 -> 3 -> 2 -> Ø
- 节点
6
没有指向其他节点,因此直接指向空
数组模拟链表
int head, e[N], ne[N], idx;
void init()
{
head = -1;
idx = 0;
}
void add_at_head(int x)
{
e[idx] = x;
ne[idx] = head;
head = idx++;
}
void add(int k, int x)
{
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx++;
}
void remove(int k)
{
ne[k] = ne[ne[k]];
}
- 示例
数组模拟邻接表
const int N = 1e6 + 10;
int h[N], e[N], ne[N], idx;
bool st[N];
void init()
{
memset(h, -1, sizeof h);
}
void add(int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
- 示例
DFS 寻找所有路径
代码
#include
#include
#include
using namespace std;
const int N = 1e5;
vector<vector<int>> all;
int h[N], e[N], ne[N], idx;
bool st[N];
void add(int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
void dfs(int u, int end, vector<int>& path)
{
st[u] = true;
path.push_back(u);
if(u == end)
{
all.push_back(path);
st[u] = false;
return;
}
for(int i=h[u]; i!=-1; i=ne[i])
{
int j = e[i];
if(!st[j])
{
st[j] = true;
dfs(j, end, path);
path.pop_back();
}
}
st[u] = false;
}
int main()
{
memset(h, -1, sizeof h);
add(1, 2); add(1, 3);
add(2, 4);
add(3, 4);
add(4, 5);
add(5, 6);
vector<int> path;
dfs(1, 6, path);
for(int i=0; i<all.size(); ++i)
{
for(int j=0; j<all[i].size(); ++j)
cout << all[i][j] << ' ';
cout << endl;
}
return 0;
}
输入数据对应图
// 添加边
add(1, 2); add(1, 3);
add(2, 4);
add(3, 4);
add(4, 5);
add(5, 6);
输出
1 3 4 5 6
1 2 4 5 6
BFS 寻找所有路径
代码
#include
#include
#include
#include
using namespace std;
const int N = 1e5;
vector<vector<int>> all;
int h[N], e[N], ne[N], idx;
void add(int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
void bfs(int start, int end, int n)
{
queue<vector<int>> q;
queue<vector<bool>> q_st;
q.push({start});
q_st.push(vector<bool>(n + 1, false));
while(q.size())
{
vector<int> path = q.front(); q.pop();
vector<bool> st = q_st.front(); q_st.pop();
int last = path.back();
st[last] = true;
if(last == end)
{
all.push_back(path);
continue;
}
for(int i=h[last]; i!=-1; i=ne[i])
{
int j = e[i];
if(!st[j])
{
vector<int> next_path(path);
next_path.push_back(j);
vector<bool> next_st(st);
next_st[j] = true;
q.push(next_path);
q_st.push(next_st);
}
}
}
}
int main()
{
memset(h, -1, sizeof h);
add(1, 2); add(1, 3);
add(2, 4);
add(3, 4); add(3, 5);
add(4, 5); add(4, 1);
add(5, 6);
vector<int> path;
bfs(1, 6, 6);
for(int i=0; i<all.size(); ++i)
{
for(int j=0; j<all[i].size(); ++j)
cout << all[i][j] << ' ';
cout << endl;
}
return 0;
}
输入数据对应图
// 添加边
add(1, 2); add(1, 3);
add(2, 4);
add(3, 4); add(3, 5);
add(4, 5); add(4, 1);
add(5, 6);
输出
1 3 5 6
1 3 4 5 6
1 2 4 5 6
备注
写在后面