图论理论基础
**种类:**有向图、无向图、加权有向图
**度:**连到一个节点的线的数量,出度、入度
**连通性:**连通图(任意节点可到达另一节点),强连通图(有向图基础上连通),连通分量(无向图中的极大连通子图)、强连通分量(有向图中的极大强连通子图)
**图的构造方式:**朴素构造(数组)、邻接矩阵(二维矩阵)、邻接表(数组+链表)
**图的遍历方式:**深度优先搜索、广度优先搜索
深搜理论基础
从起点到终点有多少条路径,或者求最短路径。思路为一直搜索到头再回溯找别的路
深搜三部曲
1.确定函数返回类型和参数变量,基本都是
cpp
void dfs(图, 当前节点)
**2.终止条件:**到达终点或者找到了遍历过的节点
3.处理节点:
对于每一个节点,先处理,再递归调用,再回溯
98. 所有可达路径
本题用到了深搜三部曲,构造图,打印路径。
注意事项
-
本题n表示节点数、m表示边数看,不要搞混;
-
图如果用邻接矩阵来实现,那么就是用**节点数+1作为边长(因为节点从1开始,顺序增加,如果从0开始,就不需要+1了)**的一个正方形。
3. 构造图时,用while(m--),也就是有多少条边就有多少个位置(节点a到节点b)要赋1;
- 回溯时,遍历节点,需要遍历所有节点,看当前节点和哪个节点有连接,所以起始是1,遍历到终点节点
深搜三部曲
处理节点的逻辑是:
遍历所有节点,看当前节点和哪个节点有边,如果有边,就把有边的那个节点加入路径
然后把该节点作为当前节点,继续搜索边,所以递归调用dfs(grath, i, end);
然后回溯 ,也就是去遍历其他和当前节点有边的节点,目的是找不同的路径。
cpp
#include<iostream>
using namespace std;
#include<vector>
vector<vector<int>> result;
vector<int> path;
void dfs(vector<vector<int>>& grath, int cur, int end){
if(cur == end){
result.push_back(path);
return;
}
for(int i=1; i<=end; i++){
if(grath[cur][i] == 1){
path.push_back(i);
dfs(grath, i, end);
path.pop_back();
}
}
}
int main(){
int m,n,s,t;
cin>>n>>m;
vector<vector<int>> grath(n+1,vector<int>(n+1,0));
while(m--){
cin>>s>>t;
grath[s][t] = 1;
}
path.push_back(1);
dfs(grath, 1, n);
if(result.size()==0) cout<<-1<<endl;
for(const auto& pa:result){
for(int i = 0;i<pa.size()-1;i++) cout<<pa[i]<<" ";
cout<<pa[pa.size()-1]<<endl;
}
}