The GC will collect any object that is not referenced by a root object. Root objects are typically objects referenced by all appdomains (i.e. loaded assemblies/type objects), global and static object references, all object references on each thread's respective stack plus any object reference currently loaded into a CPU register.
At collection time, the GC walks the references of all known root objects and marks any object it finds along the way as "in use". When done, any objects not marked can be safely collected.
So if none of your objects are referenced (directly or indirectly) by a root object, it does not matter if there are cyclic references. They will all be eligible for collection regardless. I say eligible, because the GC uses three different strategies for collecting eligible objects, and for performance reasons only one of those collects all eligible objects when run.
Normally you won't have to think about this, it just works. But there is a lot more to garbage collection and you still need to understand the fundamentals of it in order to understand memory management and write bug free code that does not leak resources etc. Therefore its something every .NET developer should take a look at. Here are a few resources that explain more about how the CLR does garbage collection.
MSDN - Garbage Collector Basics and Performance Hints (Rico Mariani)
MSDN Magazine - Garbage Collection (Part 1): Automatic Memory Management in the Microsoft .NET Framework (Jeffrey Richter)
MSDN Magazine - Garbage Collection (Part 2): Automatic Memory Management in the Microsoft .NET Framework (Jeffrey Richter)