zoukankan      html  css  js  c++  java
  • 链式前向星

    关于前向星


    前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序,

    并记录下以某个点为起点的所有边在数组中的起始位置和存储长度,那么前向星就构造好了.

    用len[i]来记录所有以i为起点的边在数组中的存储长度.

    用head[i]记录以i为边集在数组中的第一个存储位置.

    前向星的实现


    先举个例子吧,给一个有向图,读入各边的起点和终点

    边数:7
    起点    终点
    1        2
    2        3
    3        4
    1        4
    4        5
    5        1
    5        3

    我们先把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序

    排序后得到:

    1: 1 2
    2: 1 4
    3: 2 3
    4: 3 4
    5: 4 5
    6: 5 1
    7: 5 3

    然后我们用len,head数组进行存储操作

    head[1]=1,len[1]=2
    head[2]=3,len[2]=1
    head[3]=4,len[3]=1
    head[4]=5,len[4]=1
    head[5]=6,len[5]=2

    这样的储存方式很直观,一般的新手都喜欢用

    但是利用前向星会有排序操作,如果用快排时间至少为O(nlog(n))

    这时候我们就需要引入一个更加优秀的算法——链式前向星

    链式前向星


    由于在很多图论算法中都要用到链式前向星的存储方式,所以正确深入地理解链式前向星是每一个OIer都应该做到的

    先来看看代码

    先建个结构体

    struct Edge{
        int next,to;
        int w;//this is the weight of each edge
    }edge[M+5];//M is the total_number of the graph_edges

    其中edge[i].to表示第i条边的终点,edge[i].next表示与第i条边同起点的下一条边的存储位置,edge[i].w为边权值.

    然后再加一个head数组,用head[i]记录以i为边集在数组中的最后一个存储位置.

    int head[M];//M is the total_number of the graph_edges

    有了结构体,我们该如何建边呢,别着急,先放上代码

    int cnt=0;
    void add(int u,int v,int w){
        edge[cnt].to=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;
    }

    很明显,head[i]保存的是以i为起点的所有边中编号最大的那个,而把这个当作顶点i的第一条起始边的位置.

    这样在遍历时是倒着遍历的,也就是说与输入顺序是相反的,不过这样不影响结果的正确性.

    建好了边,我们又改如何遍历呢

    for(int u=1;u<=n;u++)//n is the total_number of points
    for(int i=head[u];~i;i=edge[i].next)

    至此,基础概念的讲解就结束了

  • 相关阅读:
    devise 异步发邮件
    ubuntutweak for lucid
    960gs blueprint
    Amoeba for mysql 0.31发布(读写分离、负载均衡、Failover、数据切分)
    Google App Servlet容器转型 – 从Tomcat到Jetty
    DBeaver
    用simple from暂不用formtastic
    [SQL Server]ORDER BY的问题
    PHP pathinfo() 函数
    php中使用head进行二进制流输出,让用户下载PDF等附件的方法
  • 原文地址:https://www.cnblogs.com/muzu/p/7709632.html
Copyright © 2011-2022 走看看