【问题标题】:Best way to implement a graph without STL?在没有 STL 的情况下实现图形的最佳方法?
【发布时间】:2013-07-15 20:31:36
【问题描述】:

我被分配了一个项目,我必须接受一堆节点,以及在某些节点之间具有权重的边。

然后我必须使用此信息为图的每个连接组件找到最小生成树(因此,如果图有两个连接组件,我需要创建两个生成树)

问题是我不能使用任何 STL 库,除了 .

我知道我需要创建自己的数据结构,但我不知道我需要哪些。我想最小堆对于找到要使用的最低权重边缘很有用,但是我将如何为每个连接的组件创建一个最小堆?

我在想我需要实现 union-find 来组织连接的组件集。

为此我还需要实现哪些其他数据结构?

【问题讨论】:

    标签: data-structures tree graph-theory minimum-spanning-tree


    【解决方案1】:

    对于 union-find,您需要实现 DISJOINT SET。

    这里是使用简单数组的简单实现.. 看看

    // Disjoint Set implementation
    // Shashank Jain
    
    #include<iostream>
    #define LL long long int
    #define LIM 100005
    using namespace std;
    int p[LIM],n; // p is for parent
    int rank[LIM];
    void create_set()
    {
        for(int i=1;i<=n;i++)
        {
            p[i]=i;
            rank[i]=0;
        }
    }
    int find_set(int x)
    {
        if(x==p[x])
            return x;
        else    
        {
            p[x]=find_set(p[x]);
            return p[x];
        }           
    }
    void merge_sets(int x,int y)
    {
        int px,py;
        px=find_set(x);
        py=find_set(y);
        if(rank[px]>rank[py])
            p[py]=px;
        else
        if(rank[py]>rank[px])
            p[px]=py;
        else
        if(rank[px]==rank[py])
        {
            p[px]=py;
            rank[py]++;
        }               
    }
    int main()
    {
        cin>>n; // no: of vertex , considering that vertex are numbered from 1 to n
        create_set();
        int a,b,q,i;
        cin>>q; // queries
        while(q--)
        {
            cin>>a>>b;
            merge_sets(a,b);
        }
        for(i=1;i<=n;i++)
        {
            cout<<find_set(i)<<endl; // vertex having same value of find_set i.e same representative of set are in same subset  
        }
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      我将假设您可以选择您的 MST 算法并且输出是边列表。 Borůvka's algorithm 实现起来很简单,除了图形和不相交的集合结构之外不需要任何数据结构。相比之下,Prim 的算法需要一个优先级队列和一些逻辑来处理断开连接的图,而 Kruskal 的算法需要一个不相交的集合结构一个排序算法。我会像这样设置数据结构。每个事件顶点-边对都有一个邻接记录。

      struct Adjacency;
      
      struct Edge {
          int weight;
      };
      
      struct Vertex {
          struct Adjacency *listhead;  // singly-linked list of adjacencies
          struct Vertex *parent;  // union-find parent
      };
      
      struct Adjacency {
          struct Adjacency *listnext;
          struct Edge *edge;
          struct Vertex *endpoint;  // the "other" endpoint
      };
      

      【讨论】:

        猜你喜欢
        • 2021-08-27
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 2015-04-22
        • 1970-01-01
        • 1970-01-01
        • 2013-04-13
        • 1970-01-01
        相关资源
        最近更新 更多