zoukankan      html  css  js  c++  java
  • 图的bfs遍历模板(邻接矩阵存储和邻接表存储)

    bfs遍历图模板伪代码:

     1 bfs(u){            //遍历u所在的连通块
     2     queue q;
     3     //将u入队
     4     inq[u] = true;
     5     while (q非空){
     6         //取出q的队首元素u进行访问
     7         for (从u出发可达的所有的顶点v){
     8             if (inq[v] == false){            //如果v未曾加入过队列
     9                 //将v入队;
    10                 inq[v] = true;
    11             }
    12         }
    13     }
    14 }
    15 
    16 BFSTraversal(G){            //遍历图G
    17     for (G的所有顶点u){
    18         if (inq[u] == false){
    19             BFS(u);
    20         }
    21     }
    22 }

    邻接矩阵版:

     1 const int MAXV = 1000;
     2 
     3 const int INF = 10000000;
     4 
     5 //邻接矩阵版
     6 int n, G[MAXV][MAXV];        //n为顶点数,MAXV为最大顶点数
     7 bool inq[MAXV] = { false };
     8 void bfs(int u){                //遍历u所在的连通块
     9     queue<int> q;                //定义队列q
    10     q.push(u);                    //将初识点u入队
    11     inq[u] = true;                //设置u已经被加入过队列
    12     while (!q.empty()){            //只要队列非空
    13         int u = q.front();            //取出队首元素
    14         q.pop();                            //将队首元素出队
    15         for (int v = 0; v < n; v++){                    
    16             if (inq[v] == false && G[u][v] != INF){        //如果u的邻接点v未曾入过队列
    17                 q.push(v);
    18                 inq[v] = true;
    19             }
    20         }
    21     }
    22 }
    23 
    24 void BFSTraversal(){                    //遍历图G
    25     for (int u = 0; u < n; u++){        //枚举所有顶点
    26         if (inq[u] == false){            //如果u未曾加入过队列
    27             bfs(u);                            //遍历u所在的连通块
    28         }
    29     }
    30 }

    邻接表版(顶点类型为非结构体):

     1 vector<int> Adj[MAXV];
     2 int n;
     3 bool inq[MAXV] = { false };
     4 void bfs(int u){
     5     queue<int> q;
     6     q.push(u);
     7     inq[u] = true;
     8     while (!q.empty()){
     9         int u = q.front();            ///取出队首元素
    10         q.pop();                    //将队首元素出队
    11         for (int i = 0; i < Adj[u].size(); i++){
    12             int v = Adj[u][i];
    13             if (inq[v] = false){
    14                 q.push(v);                //将v入队
    15                 inq[v] = true;                //标记v为已经被加入过的队列
    16             }
    17         }
    18     }
    19 
    20 }
    21 
    22 void BFSTraversal(){
    23     for (int u = 0; u < n; u++){
    24         if (inq[u] = false){
    25             bfs(u);
    26         }
    27     }
    28 }

    邻接表版(顶点类型为结构体):

    vector<Node> Adj[MAXV];
    int n;
    bool inq[MAXV] = { false };
    void bfs(int u){
        queue<Node> q;
        Node start;
        start.v = u, start.w = 0, start.layer = 0;
        q.push(start);
        inq[u] = true;
        while (!q.empty()){
            Node topNode = q.front();            ///取出队首元素
            q.pop();                    //将队首元素出队
            for (int i = 0; i < Adj[u].size(); i++){
                Node node = Adj[u][i];
                node.layer = topNode.layer + 1;
                if (inq[node.v] = false){
                    q.push(node);                //将v入队
                    inq[node.v] = true;                //标记v为已经被加入过的队列
                }
            }
        }
    
    }
    
    
    void BFSTraversal(){
        for (int u = 0; u < n; u++){
            if (inq[u] = false){
                bfs(u);
            }
        }
    }

     注意:当顶点的属性不只一种或者边权的意义不只一种时,如顶点的属性除了“当前点所拥有的的资源量”还可能有 “当前点在图中的层次”,如边权除了“距离”这一意义还有“花费”属性,而用不同的存储图的方式一般用不同的方式处理这些多出来的属性,如果采用邻接矩阵的方式存储图:一般用增加一维数组二维数组来应对点属性和边权意义的增加,而如果采用邻接表的方式存储图,则一般采用定义一个结构体,在结构体中增加需要的点属性和边权属性。

    题型实战:

                  1076 Forwards on Weibo (30分)

    Weibo is known as the Chinese version of Twitter. One user on Weibo may have many followers, and may follow many other users as well. Hence a social network is formed with followers relations. When a user makes a post on Weibo, all his/her followers can view and forward his/her post, which can then be forwarded again by their followers. Now given a social network, you are supposed to calculate the maximum potential amount of forwards for any specific user, assuming that only L levels of indirect followers are counted.

    Input Specification:

    Each input file contains one test case. For each case, the first line contains 2 positive integers: N (1000), the number of users; and L (6), the number of levels of indirect followers that are counted. Hence it is assumed that all the users are numbered from 1 to N. Then N lines follow, each in the format:

    M[i] user_list[i]
    

    where M[i] (100) is the total number of people that user[i] follows; and user_list[i] is a list of the M[i] users that followed by user[i]. It is guaranteed that no one can follow oneself. All the numbers are separated by a space.

    Then finally a positive K is given, followed by K UserID's for query.

    Output Specification:

    For each UserID, you are supposed to print in one line the maximum potential amount of forwards this user can trigger, assuming that everyone who can view the initial post will forward it once, and that only L levels of indirect followers are counted.

    Sample Input:

    7 3
    3 2 3 4
    0
    2 5 6
    2 3 1
    2 3 4
    1 4
    1 5
    2 2 6
    

    Sample Output:

    4
    5

    题目大意要求:以某点开始,统计它L层以内所有点的个数

    代码:

     1 #include <stdio.h>
     2 #include <queue>
     3 #include <vector>
     4 #include <string.h>
     5 using namespace std;
     6 
     7 
     8 // 邻接矩阵版
     9 const int maxv = 1010;
    10 
    11 int n, G[maxv][maxv] = { 0 };        // n 为顶点数
    12 bool inq[maxv] = { false };        // 如果对应下标的值为true, 则表示i已经被访问过了
    13 int l, k;        // 层数和查询数量
    14 
    15 //struct Node{
    16 //    int v, layer;
    17 //};
    18 
    19 int layer[maxv] = { 0 };
    20 
    21 int BFS(int u){
    22     int ans = 0;
    23     queue<int> q;
    24     layer[u] = 0;
    25     q.push(u);
    26     inq[u] = true;
    27     while (!q.empty()){
    28         int top = q.front();
    29         q.pop();
    30         for (int v = 1; v <= n; v++){
    31             if (G[top][v] != 0 && inq[v] == false && layer[top] < 3){
    32                 layer[v] = layer[top] + 1;
    33                 inq[v] = true;
    34                 q.push(v);
    35                 ans++;
    36             }
    37         }
    38     }
    39     return ans;
    40 }
    41 
    42 
    43 int main()
    44 {
    45     // 输入数据
    46     // freopen("in.txt", "r", stdin);
    47     scanf("%d %d", &n, &l);
    48     int n2;
    49     for (int v = 1; v <= n; v++){
    50         // 有向图,且逆着存储数据
    51         scanf("%d", &n2);
    52         int u;
    53         for (int j = 0; j < n2; j++){
    54             scanf("%d", &u);
    55             G[u][v] = 1;
    56         }
    57         
    58     }
    59 
    60     // 从不同的起点开始遍历图,返回一个点赞量
    61     scanf("%d", &k);
    62     for (int i = 0; i < k; i++){
    63         // 将inq数组初始化
    64         memset(inq, false, sizeof(inq));
    65         memset(layer, 0, sizeof(layer));
    66         int u;
    67         scanf("%d", &u);
    68         int maxForwards = BFS(u);
    69         printf("%d
    ", maxForwards);
    70     }
    71 
    72     // fclose(stdin);
    73     return 0;
    74 }
  • 相关阅读:
    DLL导出类避免地狱问题的完美解决方案
    WorldWind源码剖析系列:影像图层类ImageLayer
    WorldWind源码剖析系列:插件类Plugin、插件信息类PluginInfo和插件编译器类PluginCompiler
    多线程中的锁系统(一)-基础用法
    [转]分布式计算框架综述
    C#自定义控件开发
    GDI+编程小结
    C#自定义控件
    WorldWind源码剖析系列:窗口定制控件类WorldWindow
    WorldWind源码剖析系列:四叉树瓦片集合类QuadTileSet
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/11480981.html
Copyright © 2011-2022 走看看