if it can duplicate, you use a different container.
a graph..
can be given a set of rules that makes it a tree
which can be reduced with more rules to a binary tree
or a different set of rules can make a linked list
so you CAN make a graph using the textbook design of pointers to self, the key concepts you used to make lists, and trees in school:
1 2 3 4 5
|
struct graph
{
something data;
vector<graph*> outgoing_links;
}
|
where each node can go to N other nodes via the links. The links could have a cost attached to them, you could use a <pair> for that or whatever.
this is woefully inefficient in the long run, of course -- same as how textbook design pointer trees and LL are inefficient -- so after understanding the above "shape" of the data structure, you end up with the suggestions for performance and code simplification reasons. A container that lets you get to any node, or touch each node, saves having to traverse the convoluted and cyclical structures to do a simple search or whatnot, and adjacency lists do the same for traversing it properly if you need that.