Prim's Algorithm - Minimum Spanning Tree
1. Keeping references to potentially dangling pointers

I can see a potential problem with the line

vertices[ver.first].parent = &amp;vertices[curr_vertex];


if the std::vector&lt;Vertex&gt; vertices would be reorganised due to changes in length.
The address you take there isn't stable.

Maybe a better solution would be to keep a 

std::vector&lt;std::unique_ptr&lt;Vertex&gt;&gt; vertices;


instead of keeping copies of the Vertex instances.

Then you can change 

vertices[ver.first].parent = &amp;vertices[curr_vertex];


to

vertices[ver.first].parent = vertices[curr_vertex].get();


Since all the vertices are in private scope of the Graph class the std::unique_ptr&lt;Vertex&gt; instances stored to the vertices vector will never invalidate, as long you guarantee to remove all child Vertex instances when a parent Vertex instane is removed from the graph (Well, that's not an operation in question here, but needs to be considered for production code).

2. Inconsistent error handling

Here

else
{
    std::cerr &lt;&lt; "Negative weight\n";
}


you just use kind of errorneous input being reported to the console, while you throw exceptions for other cases.

For this condition you should rather do


throwing an exception
applying an assert() call in 1st place
clarify from the function signature

If Negative weight is erroneous input you should make that clear in 1st place:

  void Graph::add_edge(std::size_t src , std::size_t dest, unsigned weight)
                                                        // ^^^^^^^^


This way violations would be covered by the compiler, before runtime detects that flaw.


3. Storing unnecessary information

In your code example parent is never used besides storing the information. I am aware that you might have been simplified the actual usage of parent with this review question, but with the code context you give, that member variable doesn't make any sense.