图的遍历及其作用:
图的遍历主要分为两种:
1.深度优先遍历(dfs)
2.广度优先遍历(bfs)
1.DFS遍历:通过深度优先搜索来理解
遍历代码:
Void dfs(int k);
{
printf(“%d”,k);
f[k]=true;//将k标记为已经被遍历过的点
for (int j=1;j<=n;j++)
if ((!f[j])&& a[k][j]) dfs(j);//查找和k连通的点
}
主程序:
memset(f,0,sizeof(f));
for (int i=1;i<=n;i++)
if (!f[i]) dfs(i);
以上为邻接矩阵的DFS 复杂度:O(n^2)
邻接表:复杂度O(E)
邻接表的DFS
for (int i=link[k];i;i=e[i].next)//由link数组开始和k相连的每一条边,这句话要牢记
if (!vis[e[i].y])
vis[e[i].y]=1,dfs(e[i].y);
2.BFS遍历:结合广度优先搜索,运用队列优化:复杂度相对深度较好
Void bfs(int i);
{
memset(q,0,sizeof(q));
int head=0,tail=1;
q[1]=i; f[i]=true;
while (head<tail)
{
k=q[++head]; cout>>k;
for (int j=1;j<=n,j++)
if (a[k][j] && !f[j])//邻接表就是在这两句的基础上修改,和DFS基本类似
{
q[++tail]=j;
f[j]=true;
}
}
}
3.例题一:田野上的环HLUOJ#301
题目大意:求与1连通的所有点
基本思路:显然,通过DFS遍历找到与1相连的点,并用vis数组记录最后升序输出即可。
基本代码如下:
#include<bits/stdc++.h>
using namespace std;
struct cow
{
int y,next;
}e[600000];
int lin[5000],t=0,n,m;
bool vis[600000];
void inse(int xxx,int yyy)
{
e[++t].next=lin[xxx];
lin[xxx]=t;
e[t].y=yyy;
}//构建邻接表
void dfs(int k)
{
vis[k]=1;
for (int i=lin[k];i;i=e[i].next)
if (!vis[e[i].y]) dfs(e[i].y);
}//DFS遍历
void out(){
bool flag=1;
for (int i=1;i<=n;i++)
if (!vis[i]){
cout<<i<<endl;
flag=0;
}
if (flag) cout<<0<<endl;
}//输出结果
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int xx,yy;
cin>>xx