一、深搜与广搜
从图的某个顶点出发系统的访问图中的所有顶点,使每个顶点恰好被访问一次,这种运算操作被称为图的遍历。深搜和广搜的时间效率都是O(n×n)。
1、深搜
图的深搜与数组的dfs相似,先访问一个顶点,然后访问与这个顶点相连的未被访问的点,访问过的标记一下之后就不再访问。如果一个点的所有连接点都被访问,那么返回这个点的上一层连接点,访问上一层连接点的下一个未被访问的连接点继续遍历。
模板:
void dfs(int i){
v[i] = 1;
for(int j=1;j<=num[i];j++){
if(!v[g[i][j]])
dfs(g[i][j]);
}
}
int main(){
memset(v,0,sizeof(v));
for(int i=1;i<=n;i++){
if(!v[i])
dfs(i);
}
// ……………………
return 0;
}
2、广搜
模板
vector<int> ans;
void dfs(int s) {
vis[s] = 1;
ans.push_back(s);
for(int i = 0; i < n; i++)
if(!vis[i] && g[s][i])
dfs(i);
}
int main()
{
int u, v, val;
memset(g, 0, sizeof(g));
for(int i = 0; i < m; i++) {
cin >> u >> v >> val;
g[u][v] = val;
//G[v][u] = val; //无向图
}
ans.clear();
int start;
cin >> start;
memset(vis, 0, sizeof(vis));
dfs(start);
for(int i = 0; i < s.size(); i++)
cout << ans[i] <<endl;
return 0;
}
二、一笔画问题
若一个图存在一笔画,则该路径叫做欧拉路,如果,如果最后又回到起点,那这个路径叫做欧拉回路。
定义奇点是指跟这个点相连的边数目有奇数个点。对于能够一笔画的图,我们有以下两个定理。
- 1、存在欧拉路的条件:图是联通的,有且只有两个奇点。
- 2、存在欧拉回路的条件:图是联通的,有0个奇点。
求欧拉路的算法用深搜就可以。
根据两个定理,如果去找欧拉回路,找任意一个点去深搜;如果找欧拉路,对一个奇点去深搜,时间复杂度为O(m+n),m为边数,n为点数。
三、哈密尔顿环
欧拉回路是指不重复地走过所有路径的回路,而哈密尔顿环实质不重复地走过所有点且最后还能回到起点的回路。
使用深搜即可。