C++ 如何用c++;

C++ 如何用c++;,c++,graph,C++,Graph,我想写prims和dijkstra算法来创建一个MST。但是我不知道C++中图形的最佳表示方式是什么。 我可以用两个整数对来表示一条边,例如向量0到1是一对(0,1) typedef对边; 然后prims函数将得到由边及其权重组成的向量对 void prims(vector<pair<Edge, int>>); void prims(向量); 我认为这种方法不是最好的方法,有人能告诉我什么方法是表示图形的最好方法吗?不久前,我一直在使用Dijkstra在二值图像中查

我想写prims和dijkstra算法来创建一个MST。但是我不知道C++中图形的最佳表示方式是什么。 我可以用两个整数对来表示一条边,例如向量0到1是一对(0,1)

typedef对边;
然后prims函数将得到由边及其权重组成的向量对

void prims(vector<pair<Edge, int>>);
void prims(向量);

我认为这种方法不是最好的方法,有人能告诉我什么方法是表示图形的最好方法吗?

不久前,我一直在使用Dijkstra在二值图像中查找路径。我将图形表示为结构
GraphNodes
的向量,该结构包含
连接的向量,该向量包含节点到其他节点的所有连接。每个连接都有其距离属性,即边的权重。以下是我使用的两个结构:

//forward declaration
struct GraphNode;
struct Connection {
    Connection() : distance(1) { };
    Connection(GraphNode* ptr, double distance) : ptr(ptr), distance(distance) { };
    bool operator==(const Connection &other) const;
    GraphNode* ptr;
    double distance;
};

struct GraphNode {
    GraphNode() : connections(8), predecessor(NULL), distance(-1) { };
    cv::Point point;
    double distance;
    GraphNode* predecessor;
    std::vector<Connection> connections;
};

bool Connection::operator==(const Connection &other) const {
    return ptr == other.ptr && distance == other.distance;
}
如您所见,有一个集合
unusedNodes
,其中包含迄今为止所有未使用的节点。它只包含图形节点上的指针。实际的图形表示在向量中。拥有一个集合的优点是,它总是根据某个标准进行排序。我实现了自己的sorter
GraphDistanceSorter
,它根据Dijkstra算法的距离标准对图形节点进行排序。这样,我只需从集合中选择第一个节点,并知道它是距离最小的节点:

struct GraphDistanceSorter {
    bool operator() (const GraphNode* lhs, const GraphNode* rhs) const;
};

bool GraphDistanceSorter::operator() (const GraphNode* lhs, const GraphNode* rhs) const {
    if (lhs->distance == rhs->distance) {
        return lhs < rhs;
    } else {
        if (lhs->distance != -1 && rhs->distance != -1) {
            if (lhs->distance != rhs->distance) {
                return lhs->distance < rhs->distance;
            }
        } else if (lhs->distance != -1 && rhs->distance == -1) {
            return true;
        }
        return false;
    }
}
结构图距离分类器{
布尔运算符()(常量图形节点*lhs,常量图形节点*rhs)常量;
};
bool GraphDistanceSorter::operator()(常量GraphNode*lhs,常量GraphNode*rhs)常量{
如果(左侧->距离==右侧->距离){
返回左侧<右侧;
}否则{
如果(左侧->距离!=-1和右侧->距离!=-1){
如果(左侧->距离!=右侧->距离){
返回左侧->距离<右侧->距离;
}
}否则如果(左侧->距离!=-1&&rhs->距离==-1){
返回true;
}
返回false;
}
}

在理论计算机科学中学习的两种主要图形表示方法是和

如下图所示,邻接矩阵是一个n*n矩阵,[i][j]表示节点i和节点j之间的边,因此,如果是加权图,它可以是整数,而不是未加权图的布尔值

另一方面,邻接列表是一组链表(确切地说是n集),第i集正好有我连接的节点。 在这种情况下,您将需要一些额外的方法来保存边距离,例如,您可以按照以下方式构建自己的类边

class Edge
{
     int destination, length;
     Edge* next = 0;
}
并将其用于链接列表。我是如何习惯于
std::vector a[N]
来定义对列表和
a[I][j]。首先
将是节点I和
a[I][j的第j个邻居。其次
它们之间的边的长度。 对于无向图,也可以将i添加到j邻域。 因此,它也是一种灵活的图形表示方法

现在让我们谈谈复杂性,我会尽量让它简单:

我们有n个列表,每个列表都有#(节点i外的边) 所以总数是这些数的总和,也就是边的总数。 这意味着位置复杂性是O(E),与邻接矩阵中的O(n^2)相比,稀疏图中的位置复杂性最多为5*n。(我们需要一个线性因子E来表示它)。 现在让我们考虑访问NOD X的所有邻居: 在邻接矩阵中,我们将遍历整个x行,如果它不是0,那么那里有一条边是O(N)。 在邻接列表中,x的邻接数可以达到O(N)。 但是,如果我们访问所有节点的所有邻居(在Dijkstra中更新dis数组时就是这种情况),您将需要在邻接列表中访问n个元素n次,这也是O(n^2)时间复杂度,而在邻接列表中,它正好是邻居数目的和-同样是E。这意味着我们还需要O(E)访问所有边缘的所有邻居。 sind通常在输入中给出所有边O(E)将作为计算时间通过,但是O(N^2)对于N>N>>E的约束将是一个高复杂性; for(int i=0;i>x>>y>>z; //如果从1开始,则用x和y替换1 图[x]。推回(std::生成(y,z)对); 逆[y]。推回(std::生成_对(x,z)); 未加权[x]。推回(y); 无向加权[x]。向后推(y); 无向加权[y]。向后推(x); } 返回0; }
表示图形的简单形式(查找顶点的邻域和度)


#包括
/**表示C++语言中的图**
使用名称空间std;
int main(){

也许你想考虑使用<代码> STD::tuple < /Case> s三个int,而不是嵌套对,但是我要说的是,即使你不是这个世界上最好的一个,你也可以理解一个解决方案。当你对它有更多的经验时,你总是可以改进它。表示一个连接,例如3->4,5->3,…是的,但每个对/边都有权重。好吧,我想问一下,在哪种意义上最好。内存使用?更可读?最快的插入?最快的导航?不幸的是,你不能拥有所有这些。可读性,良好的语法和常识。
struct GraphDistanceSorter {
    bool operator() (const GraphNode* lhs, const GraphNode* rhs) const;
};

bool GraphDistanceSorter::operator() (const GraphNode* lhs, const GraphNode* rhs) const {
    if (lhs->distance == rhs->distance) {
        return lhs < rhs;
    } else {
        if (lhs->distance != -1 && rhs->distance != -1) {
            if (lhs->distance != rhs->distance) {
                return lhs->distance < rhs->distance;
            }
        } else if (lhs->distance != -1 && rhs->distance == -1) {
            return true;
        }
        return false;
    }
}
class Edge
{
     int destination, length;
     Edge* next = 0;
}
#include<iostream>
#include<vector>
int main(){
    const int N = 5;
    int n, e;
    std::vector<std::pair<int, int>> graph[N], inverse[N];
    std::vector<int> unweighted[N], undirectedUnweighted[N];
    std::cin >> n >> e;
    for(int i = 0; i < e; i++)
    {
        int x, y, z;//z is length of edge
        std::cin >> x >> y >> z;
        //substitute 1 from x, y if they starts from 1
        graph[x].push_back(std::make_pair(y, z));
        inverse[y].push_back(std::make_pair(x, z));
        unweighted[x].push_back(y);
        undirectedUnweighted[x].push_back(y);
        undirectedUnweighted[y].push_back(x);
    }
    return 0;
}

#include<iostream>

/** Representing graphs in c++ programming language */

using namespace std;

int main() {

    cout << "\033[1;33mNote: if there are no neighbourhood between vertices write '-' symbol!\033[0m\n"<<endl;

    int number_of_vertices;
    cout<<"\033[1;32mPlease enter number of vertices: \033[0m";
    cin>>number_of_vertices;

    int max_num_of_neighbours;
    cout<<"\033[1;32mPlease enter maximum number of neighbours: \033[0m";
    cin>>max_num_of_neighbours;

    char array[number_of_vertices][max_num_of_neighbours];

    char vertices[number_of_vertices];

    cout<<"\033[1;33mPlease sign vertices with lowercase alphabet letters: \033[0m"<<endl;

    for(int i = 0; i < number_of_vertices; i ++) {

        cout<<(i+1)<<" = ";
        cin>>vertices[i];

    }

    for(int i = 0; i < number_of_vertices; cout<<endl, i ++) {

        cout<<"\033[1;32mPlease enter neighbours for \033[0m"<<vertices[i]<<" --> ";

        for(int j = 0; j < max_num_of_neighbours; j ++) {

            cin>>array[i][j];

        }

    }


    for(int i = 0; i < number_of_vertices; cout<<endl, i ++) {

        cout<<"\033[1;34mNeighbours for \033[0m"<<"\033[1;35m"<<vertices[i]<<"\033[0m"<<" --> ";

        int deg = 0;

        for(int j = 0; j < max_num_of_neighbours; j ++) {

            if(array[i][j] != '-') {
                deg ++;
            }

            if(array[i][j] == '-') {
                cout<<"\033[1;31m"<<array[i][j]<<"\033[0m"<<"\t";
            } else {
                cout<<"\033[1;32m"<<array[i][j]<<"\033[0m"<<"\t";
            }

        }

        cout<<"\033[1;36m"<<"deg["<<"\033[0m"<<"\033[1;35m"<<vertices[i]<<"\033[0m"<<"\033[1;36m"<<"] = "<<"\033[0m"<<deg;

    }

    cout<<endl<<"\033[1;33mRemember that '\033[1;31m-\033[0m\033[1;33m' shows when two vertices aren't adjacent!\033[0m"<<endl;


}