hust_archer

ACM菜鸟想逆袭

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  0 Posts :: 2 Stories :: 0 Comments :: 0 Trackbacks

常用链接

留言簿

我参与的团队

搜索

  •  

最新评论

关于图的搜索有两种:广度优先(bfs)深度优先 (dfs)。
以下图为例:


深度优先的基本思想简单说就是搜到底,重新搜。从v0为起点进行搜索,如果被访问过,则做一个标记,直到与v0想连通的点都被访问一遍,如果这时,仍然有点没被访问,可以从中选一个顶点,进行再一次的搜索,重复上述过程,所以深度优先的过程也是递归的过程。
深度优先访问的结果是:0->1->3->7->4->2->5->6


广度优先的基本思想是,从顶点v0出发,访问与v0相邻的点,访问结束后,再从这些点出发,继续访问,直到访问结束为止。标记被访问过的点同深搜一下,不过,广度优先一般需要用到队列。
上图广度优先的结果:
0->1->2->3->4->5->6->7

对于深度优先与广度优先的应用,在吴军的《数学之美》一书中有过介绍。

关于搜索代码如下:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#define maxn 100
using namespace std;

typedef struct
{
    int edges[maxn][maxn];  //邻接矩阵
    int n;   //顶点数
    int e;    //边数
}MGraph;

bool vis[maxn];  //标记顶点是否被访问过
void createGraph(MGraph &G) //用引用做参数
{
    int i,j;
    int s,t;  //存储顶点的编号
    int v;  //存储边的权值
    for(i=0;i<G.n;i++)  //初始化
    {
        for(j=0;j<G.n;j++)
        {
            G.edges[i][j] = 0;
        }
        vis[i] = false;
    }
    for(i = 0;i<G.e;i++) //对邻接矩阵的边赋值
    {
        scanf("%d%d%d",&s,&t,&v);  //输入边顶点的编号以及权值
        G.edges[s][t] = v;
    }
}
void dfs(MGraph G,int v)
{
    int i;
    printf("%d ",v);  //访问结点v
    vis[v] = true;
    for(int i = 0;i<G.n;i++) //访问与v相邻且未被访问过的结点
    {
        if(G.edges[v][i]!=0&&vis[i]==false)
        {
            dfs(G,i);
        }
    }
}
void dfs1(MGraph G,int v)   //非递归实现(用到了栈,其实在递归的实现过程,仍是用到了栈,所以。。。)
{
    stack<int> s;
    printf("%d",v);  //访问初始的结点
    vis[v]=true;
    s.push(v);  //入栈
    while(!s.empty())
    {
        int i,j;
        i=s.top();  //取栈顶顶点
        for(j=0;j<G.n;j++) //访问与顶点i相邻的顶点
        {
            if(G.edges[i][j]!=0&&vis[j]==false)
            {
                printf("%d ",j); //访问
                vis[j]=true;
                s.push(j);  //访问完后入栈
                break//找到一个相邻未访问的顶点,访问之后跳出循环
            }
        }
        if(j==G.n)   //如果与i相邻的顶点都被访问过,则将顶点i出栈
            s.pop();
    }
}
void bfs(MGraph G,int v)
{
    queue<int> Q;
    printf("%d",v);
    vis[v] = true;
    Q.push(v);
    while(!Q.empty())
    {
        int i,j;
        i = Q.front();  //取队首顶点
        Q.pop();
        for(j=0;j<G.n;j++) //广度遍历
        {
            if(G.edges[i][j]!=0&&vis[j]==false)
            {
                printf("%d",j);
                vis[j]=true;
                Q.push(j);
            }
        }
    }
}
int main()
{
int n,e; //建图的顶点数和边数
while(scanf("%d%d",&n,&e)==2&&n>0)
{
    MGraph G;
    G.n = n;
    G.e = e;
    createGraph(G);
    dfs(G,0);
    printf("\n");
 //   dfs1(G,0);
 
//   printf("\n");
  
//  bfs(G,0);
  
//  printf("\n");

}

return 0;
}
/*测试数据:
8 9
0 1 1
1 3 1
1 4 1
3 7 1
4 7 1
0 2 1
2 5 1
5 6 1
2 6 1
*/
posted on 2014-05-02 10:58 hust_archer 阅读(2988) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航:   博客园   博客园最新博文   博问   管理