【问题标题】:Adjacency List (Double vector) to solve graph algorithm邻接表(双向量)求解图算法
【发布时间】:2020-11-26 14:53:21
【问题描述】:

所以我使用数据类型 pair 的双向量来存储图中顶点的边和权重。通过这个实现,我正在尝试解决 Prims 算法。获得第一个边缘的过程似乎很容易,但获得其余边缘的重复循环似乎无法正常工作。对于此代码中的特定图形,输出应该是 ({2,4}, {5,6}, {4,5}, {3,4}, {2,3}, {2,7} )。我得到({2,4},{5,6},{4,5},{3,4},{2,3},{2,3})。代码如下:

#include <iostream>
#include<vector>
#include <utility>
using namespace::std;

class graphs{
private:
    vector<vector<pair<int, int>>> graph;
    int vertices;

public:
    graphs(int v){
        vertices = v;
        graph = vector<vector<pair<int, int>>>(v+1);
    }
    void insert(int v, int e, int w=0){
        graph[v].push_back(make_pair(e, w));
    }

    void prim(){
        int edges = vertices - 1, e = 0, min = 1000, u, v;
        int t[2][vertices]; // array to insert the edges
        vector<pair<int, int>> check (vertices+1);
        for(int i = 1; i<graph.size(); i++){
            for(int j = 0; j<graph[i].size(); j++){
                if(graph[i][j].second<min){
                    min = graph[i][j].second; u = i; v = graph[i][j].first;
                }
            }
        } // This for loop gets the original min value and index.
        t[0][e] = u; t[1][e] = v; check[u].first = check[v].first =-1; check[u].second = check[v].second = 1000;

        for(int i = 1; i<check.size(); i++){
            min = 1000;
            if(check[i].first != -1){
                for(int j = 0; j< graph[i].size(); j++){
                    if(graph[i][j].first == t[0][e] && graph[i][j].second<min){
                        min = graph[i][j].second; u = i; v = t[0][e];
                    }
                    else if(graph[i][j].first == t[1][e] && graph[i][j].second<min){
                        min = graph[i][j].second; u = i; v = t[1][e];
                        check[i].second = graph[i][j].second;
                    }
                }
                check[i].first = v; check[i].second = min;
                if(min == 1000){
                    check[i].first = t[1][e]; check[i].second = 1000;
                }
                else{
                    check[i].first = v; check[i].second = min;
                }
            }
        }//This for loop adjusts the check vector to show whether the rest of the vertices are closer to t[0][0] or t[1][0]
        e++;
        while(e<edges){// The repetition loop.
            min = 1000;
            for(int i = 1; i< vertices; i++){
                if(check[i].second < min && check[i].first != -1){
                    min = check[i].second; u=i; v = check[i].first;
                }
            }//This for loop finds the next min edge to put into the final array t.
            t[0][e]= u; t[1][e] = v;
            check[u].first = -1;
            for(int i = 1; i<check.size(); i++){ //This for loop adjusts the check vector in accordance with the new vertex.
                if(check[i].first != -1){
                    for(int j = 0; j< graph[i].size(); j++){
                        if(graph[i][j].first == u && graph[i][j].second<check[i].second){
                            min = graph[i][j].second;
                        }
                    }
                    check[i].first = u; check[i].second = min;
                }
            }
            e++;
        }
        for(int i = 0; i<2; i++){
            for(int j = 0; j< vertices-1; j++){
                cout<<t[i][j] << " ";
            }
            cout<< endl;
        }
    }
};
int main(int argc, const char * argv[]){
    graphs graph(7);
    graph.insert(1, 2, 25);
    graph.insert(1, 6, 5);
    graph.insert(2,1, 25);
    graph.insert(2,3, 12);
    graph.insert(2, 7, 10);
    graph.insert(3, 2, 12);
    graph.insert(3, 4, 8);
    graph.insert(4, 3, 8);
    graph.insert(4, 5, 16);
    graph.insert(4, 7, 14);
    graph.insert(5, 4, 16);
    graph.insert(5, 6, 20);
    graph.insert(5, 7, 18);
    graph.insert(6, 1, 5);
    graph.insert(6, 5, 20);
    graph.insert(7,2,10);
    graph.insert(7, 4, 14);
    graph.insert(7, 5, 18);
    graph.prim();
    return 0;
}

任何一般性的批评和提示也将不胜感激!

【问题讨论】:

  • “似乎有问题”是什么让你这么认为?对于某些输入,您是否得到错误的输出?请在问题中包含更多信息
  • 但是获取其余边缘的重复循环似乎有问题 -- 有问题吗?有什么错误?你用过调试器吗?你可以做的一件事:去掉vertices成员变量——一旦你有了vector就没有必要了,因为vector::size()告诉你向量中有多少项目。
  • int t[2][vertices]; // array to insert the edges -- 为什么这不是一个向量呢?那行代码不是有效的 C++。
  • 该代码有各种语法错误,例如试图创建一个初始值为 0 的 std::vector&lt;std::pair&lt;int,int&gt;&gt;,使用可变长度数组,以及由于您放置超过每行一个语句。请解决这个问题。一般来说,How to debug small programswhat is a debugger
  • 我添加了 vertices 成员变量,这样我就不必每次都减去 1。

标签: c++ graph prims-algorithm


【解决方案1】:
while(e<edges){// The repetition loop.
            min = 1000;
            for(int i = 1; i< vertices; i++){
                if(check[i].second < min && check[i].first != -1){
                    min = check[i].second; u=i; v = check[i].first;
                }
            }

i 必须小于或等于顶点。

            min = 1000;
            for(int i = 1; i<= vertices; i++){
                if(check[i].second < min && check[i].first != -1){
                    min = check[i].second; u=i; v = check[i].first;
                }
            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多