BFS初步的总结

来源:互联网 发布:dfx设计 java 编辑:程序博客网 时间:2024/05/22 14:16


前几天在MarkBlain的带领下学习了初步的BFS算法,然后被逼着写下这篇总结。

BFS全称Breadth First Search,中文名广度优先搜索,又称宽度优先搜索,和DFS相对。通俗来说DFS是一条路走到底,而BFS就像是把一栋大厦一层一层搜索。所以正如MarkBlain所说,在做最优路径(限定:结点到结点的耗费和深度成正比)的题时,广度优先搜索一般需要存储所有结点所以耗费空间大,但找到最优解后直接输出,耗时较短,深度优先搜索不需要存储所有结点,耗费空间较小但是有可能要将全局都搜索后再输出最优解,所以耗时较长。因此,在做题时要考虑到空间限制问题和耗时问题,灵活选择算法(PS:我好像并没有资格说这种话)。

说道BFS最简单的题就是找最短路(题目链接http://fzoj.xndxfz.com/JudgeOnline/problem.php?id=1431)这道题萌新的解法是用邻接矩阵将相连的两个结点存储,然后用链表模拟队列记录入队的结点,按顺序来遍历结点如果找到了就递归输出。这方法虽然比较笨,但是在oj上还是可以A的。下面附上代码。

#include<stdio.h>
#include<string.h>
//f数组记录两个结点是否相连, s数组记录结点是否已经入队;
int f[30][30],s[30];
struct node
{
    int data;
    node *next;
};
//搜索最短路径并输出
void bfs(int x,int y)//x是起点y是终点
{
    if(x==y)//最后输出的步奏,不想另外开一个函数了所以揉在了一起
    {
        printf("%c",x-1+'A');
        return ;
    }
    memset(s,0,sizeof(s));
    int i,flag=0;
    node *head=new node;//静态链表没有学好,所以用动态链表模拟队列
    node *p=head,*last=head;
    last->data=x;
    s[x]=1;
    last->next=new node;
    while(p->data!=-1)
    {
        for(i=1;i<=26;i++)
        {
         //如果两结点相连并且i点未入队
            if(f[p->data][i]==1&&s[i]==0)
            {
                s[i]=1;//表示i点已入队;
                last->next->next=new node;//多开一个方便设置边界条件
                last->next->next->data=-1;
                last=last->next;
                last->data=i;//正式将i入队
                if(i==y)//表示已找到最终答案;
                {
                    flag=1;//标记一下,方便跳出上层循环
                    break;
                }
            }
        }
        if(flag) break;
        p=p->next;//控制循环,不然直接死循环QAQ
    }
    if(flag)
    {
        bfs(x,p->data);//递归输出
        printf("->%c",y-1+'A');
    }
}
 
int main()
{
    int x,y,n,a,b,i;
    memset(f,0,sizeof(f));
    scanf("%d %d %d",&x,&y,&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d %d",&a,&b);
        f[a][b]=1;
        f[b][a]=1;
    }
    bfs(x,y);
}

然后就是营救、水缸灌水等题目,这些题目个人认为都是基于求最短路的基础之上至于代码,因为写得太难看了就不贴了。

0 0