vendredi 1 mai 2020

Efficient adjacency list representation in C++

The standard representation of an adjacency list for weighted graphs in C++ is an array of vectors of pairs is often (ie. vector<pair<int, int>> adj[N]). I don't have any issues with this when I know the size of N at compile time, and if N isn't too big. However, when N is only known at run-time (a variable), I have to resort to making N the upper bound of the adjacency list size. I often run into segmentation faults where, if I am not mistaken, the array max_size is exceeded. For example, I am currently encountering this problem with the bounds N <= 3000*2999/2 (about 45000000).

Below is an example with Prim's MST algorithm in which I get a Segmentation Fault. How can I avoid this? Should I consider other data types? Thanks!

Edit: I could just use a vector and initialize it with a loop from 1 to n, but I'm wondering if there's a more efficient way.

int prims(int n, vector<vector<int>> edges, int start) {
vector<pair<int, int>> adj[45000000];
for(vector<int> edge : edges){
    adj[edge[0]].push_back({edge[2], edge[1]});
    adj[edge[1]].push_back({edge[2], edge[0]});
}
vector<bool> visited;
for(int i=0; i<n; i++){
    visited.push_back(false);
}
int dist = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push({0, start});
while(!pq.empty()){
    pair <int, int> p = pq.top();
    pq.pop();
    // cout << "top is " << p.second << "\n";
    if(visited[p.second]) continue;
    visited[p.second] = true;
    dist += p.first;
    for(pair<int, int> j : adj[p.second]){
        if(!visited[j.second]){
            pq.push(j);
        }
    }
}
return dist; }

Aucun commentaire:

Enregistrer un commentaire