Smart pointers are how C++ exemplifies ownership of data and its lifetime.
unique_ptrs are sole owners of a piece of data whose lifetime is that of the unique_ptr itself. So if you have a unique_ptr to an allocation, the allocation is deallocated when the unique_ptr dies.
shared_ptrs represent shared ownership of a piece of data. The data lives as long as the last remaining smart_ptr does. This allows you to manage data across something like threads. By returning shared_ptrs to data, you can safely ensure that it'll eventually be freed even when your code has a large degree of asynchronousness.
weak_ptrs don't claim ownership of a piece of data until you attempt to access it in which case, it has a method that creates a shared_ptr for you to access the data with. It's a neat little tool. More info here: std::weak_ptr - cppreference.com
I'm not sure about the last one. But yeah, you can look up things like shared_ptr circular references and the resulting memory leaks and that'll give you an idea of why graph-based structures benefit from a combination of shared and weak pointers.
This is a good link too: Smart pointer - Wikipedia