Я работаю над составлением задачи, заданной для внутриуровневого курса CS, и придумал вопрос, который на первый взгляд кажется очень простым:
Вам предоставляется список людей с именами их родителей, даты их рождения и даты их смерти. Вы заинтересованы в том, чтобы выяснить, кто в какой-то момент своей жизни был родителем, прародителем, прабабушкой и т.д. Разработать алгоритм, чтобы помечать каждому человеку эту информацию как целое число (0 означает, что у человека никогда не было ребенок, 1 означает, что человек был родителем, 2 означает, что человек был дедушкой и бабушкой и т.д.)
Для простоты вы можете предположить, что семейный граф является DAG, неориентированной версией которого является дерево.
Интересная задача здесь заключается в том, что вы не можете просто взглянуть на форму дерева, чтобы определить эту информацию. Например, у меня 8 пра-прабабушек и бабушек, но поскольку ни один из них не был жив, когда я родился, в их жизни ни один из них не был великим прабабушкой и бабушкой.
Лучший алгоритм, который я могу придумать для этой проблемы, выполняется во времени O (n 2), где n - количество людей. Идея проста - начать DFS с каждого человека, найдя более далекого потомка в генеалогическом древе, которое родилось до даты смерти этого человека. Тем не менее, я уверен, что это не оптимальное решение проблемы. Например, если граф - это всего два родителя и их n детей, то проблема может быть решена тривиально в O (n). Я надеюсь, что это какой-то алгоритм, который либо превосходит O (n 2), либо время выполнения которого параметризуется по форме графика, что делает его быстрым для широких графов с грациозным деградации до O ( n 2) в худшем случае.