结训赛第一次复习:图的遍历(DFS&&BFS)

不得不说我图的这边学的很用心了,但依旧还是有很多带题不会

首先我们来看一下这两种的区别,我们应该在什么题里用?这是我自己总结的一些

https://blog.csdn.net/weixin_44067773/article/details/87471377

那我们再来看一下二者的定义,他们是如何运行的

BFS:就是一直往深处走,走的地方标记一下然后递归回退到其他没走的点,在走,在标记,知道结束

DFS:先找离跟最近的节点,然后把他们压入队列,再把他们当作根,再找离他们最近的结点,依次进行

那么如何写呢:

BFS:http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2717/pid/2107

#include<stdio.h>
#include<string.h>
int map[105][105];//图
int vis[105];//标记该点是否已经走到
int k;
void dfs(int i)
{
    vis[i]=1;
    if(i==0)
        printf("%d",i);
    else
        printf(" %d",i);
    int j;
    for(j=0;j<k;j++)
    {
        if(!vis[j]&&map[i][j])//这一步循环从0开始,先把0的vis=1,然后在往后加(此时0不符合if判断)然后在换成1,1符合再标记输出1,然后再从1(2,3,由于1没有到达2和3的)然后再往下循环
            dfs(j);//i->j没有走过dfs
    }
}
int main()
{
    int u,v;
    int m,n;
    while(scanf("%d",&n)!=EOF)
    {
        while(n--)
        {
            memset(map,0,sizeof(map));
            memset(vis,0,sizeof(vis));
            scanf("%d %d",&k,&m);
            while(m--)
            {
                scanf("%d %d",&u,&v);
                map[u][v]=1;
                map[v][u]=1;//双向图,便于回撤和前进
            }//如果vis为假执行(vis所代表的数没被扫过)
                dfs(0);
                printf("\n");
        }
    }
    return 0;
}

DFS:邻接矩阵实现法:

http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2717/pid/2141

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int tu[500][500];
int vis[500];
int ans[500];
int k,num;
void bfs(int t)
{
    int v,i;
    queue<int>Q;
    ans[num++]=t;
    vis[t]=1;
    Q.push(t);
    while(!Q.empty())
    {
        v=Q.front();
        Q.pop();
        for(i=0;i<=k-1;i++)
        {
            if(!vis[i]&&tu[v][i])
            {
                vis[i]=1;
                ans[num++]=i;
                Q.push(i);
            }
        }
    }
}
int main()
{
    int n,m,t,u,v,i;
    scanf("%d",&n);
    while(n--)
    {
        memset(tu,0,sizeof(tu));
        memset(vis,0,sizeof(vis));
        scanf("%d %d %d",&k,&m,&t);
        for(i=0;i<=m-1;i++)
        {
            scanf("%d %d",&u,&v);
            tu[u][v]=tu[v][u]=1;
        }
        bfs(t);
        for(i=0;i<=num-1;i++)
        {
            if(i==num-1)
                printf("%d\n",ans[i]);
            else
                printf("%d ",ans[i]);
        }
    }
    return 0;
}
人工debug:我们先把0(开头)推进去,找到离0最近的n个结点,在标记,在找离这n个结点最近的n2个结点,标记,再把他们推进去

邻接表可以想象成把数组竖起来然后每个后面都接上相应的结点

下面是邻接表法:适用于数据量较大的题目:

http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2717/pid/2142

参考代码:

https://blog.csdn.net/axuhongbo/article/details/60356923

猜你喜欢

转载自blog.csdn.net/weixin_44067773/article/details/87879456