using System.Collections.Generic;
using System.Net.Sockets;
using System.Security.Policy;
using System.Threading.Tasks;
public Name FullName { get; set; }
public Address Address { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Street { get; set; }
public string City { get; set; }
public void Init(Person[] persons)
int FindMinRelation( Person pA, Person pB)
static void Main(string[] args)
var people = new List<(string, string)>
("John", "123 Fake st."),
("John", "456 Fake st."),
("Alice", "456 Fake st."),
("Alice", "789 Fake st."),
("Alice2", "456 Fake st."),
("Alice3", "456 Fake st."),
var result = ShortestPath(people, ("John", "123 Fake st."), ("Bob", "789 Fake st."));
Console.WriteLine(result);
public static int ShortestPath(List<(string, string)> people, (string, string) a, (string, string) b)
var names = new Dictionary<string, List<(string, string)>>();
var addresses = new Dictionary<string, List<(string, string)>>();
foreach (var p in people)
var (p_name, p_address) = p;
if (!names.ContainsKey(p_name))
names[p_name] = new List<(string, string)>();
if (!addresses.ContainsKey(p_address))
addresses[p_address] = new List<(string, string)>();
addresses[p_address].Add(p);
var queue = new Queue<((string, string), int)>();
var visited = new HashSet<(string, string)>();
var namesUsed = new HashSet<string>();
var addressesUsed = new HashSet<string>();
var (p, distance) = queue.Dequeue();
if (p.Equals(b)) return distance;
if (visited.Contains(p)) continue;
var (p_name, p_address) = p;
if (!namesUsed.Contains(p_name))
foreach (var q in names[p_name])
queue.Enqueue((q, distance + 1));
if (!addressesUsed.Contains(p_address))
addressesUsed.Add(p_address);
foreach (var q in addresses[p_address])
queue.Enqueue((q, distance + 1));