• 图的存储方式


    昨天 听caicai讲了几种关于图的存储方式 又学了好多  家有caicai 如有一宝 -> 转自 晓爷

    下面 我所讲的 都是基于 有向图的建图方式 

    i:

    map[a][b] ---最基础的邻接矩阵  直接用二维数组

    ii:

     1 struct graph
     2 {
     3     int num;  // ---指向 下一个顶点 ( 表示当前已经与 该顶点相邻的个数 )
     4     int next[x]; // -- 与 该顶点 第( x+1 )个相邻的点的标号
     5     int dist[x]; // -- 与 该顶点 第 ( x+1 )个相邻的点与该点之间的距离 --通过它来进行松弛操作
     6     
     7 }mp[y] 
     8 bool vis[y] // -- 各个顶点 是否已经被访问过 在某个状态中 如 在spfa中 表示 是否已经入队
     9 int dist[y] // -- 源点 -> 各个顶点的距离
    10 // -- 这里的 next 和 dist 数组 是相对应的 所以 数组大小声明为相同
    11 int main()
    12 {
    13     int temp;
    14     scanf( "%d %d %d" , &from , &to , &dist );
    15     temp = mp[from].num;
    16     mp[from].next[temp] = to;
    17     mp[from].dist[temp] = dist;
    18     mp[from].num++;
    19     // temp++ 这是 错的 千万不要犯这种错误
    20 }
    21 
    22 // 或者 可以用下面 这种方式 代码更加简洁 但可读性没有上面的好
    23     mp[from].next[ mp[from].num ] = to;
    24     mp[from].dist[ mp[from].num++ ] = dist;
    View Code

    iii:

     1 // y -- 顶点个数
     2 // x -- 与 该顶点 相邻的顶点个数
     3 
     4 struct graph
     5 {
     6     int num;  // ---指向 下一个顶点 ( 表示当前已经与 该顶点相邻的个数 )
     7     int next[x]; // -- 与 该顶点 第( x+1 )个相邻的点的标号
     8     int dist[x]; // -- 与 该顶点 第 ( x+1 )个相邻的点与该点之间的距离 --通过它来进行松弛操作
     9     
    10 }mp[y] 
    11 bool vis[y] // -- 各个顶点 是否已经被访问过 在某个状态中 如 在spfa中 表示 是否已经入队
    12 int dist[y] // -- 源点 -> 各个顶点的距离
    13 // -- 这里的 next 和 dist 数组 是相对应的 所以 数组大小声明为相同
    14 
    15 iii:
    16 
    17 // num --- 边的总数 每有一条边的加入 就+1
    18 // x --- 顶点的个数
    19 struct garph
    20 {
    21     int to;    // 当结构体标号为num时 相邻的边的顶点
    22     int dist;  // 当结构体标号为num时 相邻的边的距离
    23     int next;  // 当结构体标号为num时 记录这条边的出发点的前面出现过的结构体标号,就是一个向前查询 类似于一个索引 很高效 通过是否为-1 来判断循环终止 
    24 }edge[x*3];    // 边的条数
    25 
    26 int head[x];   //  指向有着相同源点的顶点的标号   head的下标 即当前边的顶点的下标 
    27 
    28 void addedge( int from , int to , int dist )
    29 {
    30     edge[num].to = to;              //传递 相邻边的顶点
    31     edge[num].dist = dist;          //传递 距离
    32     edge[num].next = head[from];  //通过head数组 来查询在前面的输入中 是否已经出现过相同的源点 如果有 就在此处指向它 方便后面的for遍历查询
    33     head[from] = num;             //使顶点标号为from的结点 指向 该结构体标号
    34     num++;                        
    35 }
    36 
    37 int main()
    38 {
    39     memset( head , -1 , sizeof(head) );  // 因为我是从0~n 给顶点标号 那么 -1 是代表无前驱指向 当然  如果是从 1~n的 我当然可以初始化为0
    40     scanf( "%d %d %d" , &from , &to , &dist )
    41     addedge( from , to , dist );    
    42     for( int i = head[now] ; i!=-1 ; i = edge[i].next )//实现方式
    43 }
    View Code

    iV:

    上述的存储方式 都是放在二维数组 或者 结构体中 不具备灵活性 我们可以将它放在 容器 vector中 当然 这样可以节省内存 同时我们也要也牺牲时间的代价来获得  用何种方式 还得看具体 情况
    通过vector<class>vec[num]  来操作
    class---> 基本数据类型 或 自定义数据类型

    这里 还有一篇 讲的比我更为透彻 超神 -> click it

    如果 有任何不对的地方 请给我指出来  为了不误导后面的无意看到此文的人

    just follow your heart
  • 相关阅读:
    浅谈随机化算法
    SPSS问题
    羽毛球技术
    三大线性排序之桶排序
    Java产生随机数
    Java堆栈详解
    三大线性排序之基数排序
    指针 和 数组
    复制构造函数 与 赋值函数 的区别
    【c++】类中的const成员
  • 原文地址:https://www.cnblogs.com/radical/p/3694931.html
Copyright © 2020-2023  润新知