Примечания к исследованию разработки и анализа алгоритмов 07 | Вызов обновлений в августе

алгоритм

Это седьмой день моего участия в августовском испытании обновлений. Узнайте подробности мероприятия:  Испытание августовского обновления

Разработка и анализ алгоритмов Тема 1:

Поиск остовного дерева с минимальным радиусом в неориентированном связном графе

Цель:

Освойте использование графиков для разработки и реализации алгоритмов

Научитесь использовать списки смежности для построения и вывода ориентированных графов.

Освойте использование обхода в ширину (DFS) для вычисления глубины вершин.

Освойте использование алгоритмов динамического программирования, чтобы найти остовное дерево с наименьшим радиусом.

содержание:

1. Введите количество вершин и ребер ориентированного графа, а также начало и хвост каждого ребра.

2. Функция проектирования использует список смежности для представления создания и вывода неориентированного связного графа.

3. Функция проектирования использует обход в ширину для вычисления максимальной глубины поддерева с каждой вершиной в качестве корня дерева.

4. Функция проектирования использует алгоритм динамического программирования для вычисления максимальной глубины поддерева, образованного поддеревом, представленным вершиной и соседними с ней точками.

5. Вызовите функцию для вывода остовного дерева минимального радиуса неориентированного связного графа.

В соответствии со списком смежности графа представлен неориентированный связный граф, а алгоритм реализации поиска минимального радиуса посредством обхода в ширину и алгоритм динамического программирования выглядит следующим образом, основной код и комментарии:

void getDepth(int id)

{

//如果访问过就不再访问

if (v[id]) return;

//标记未访问结点为访问状态

v[id] = true;

head *curPtr = heads[id];

//孤立点的最大深度是0,所以maxD的初始值为0

int maxD = 0;

//遍历邻接表

while (curPtr)

{

//邻居结点的id

int toId = curPtr->toId;

//如果当前邻居点没有处理过,那么需要借助第一遍DFS时生成的countv数组计算以当前结点id以及它的邻居结点toId组成的子树的最大深度

if (!v[toId])

{

//记录

curPtr->maxDepth = countv[toId];

if (countv[toId] > maxD) maxD = countv[toId];

}

//如果当前邻居点处理过了,那需要利用当前邻居结点toId的结果来得到id的状态值

else

{

//遍历toId的所有邻居toIdd。toIdd构成的子树+toId+Id作为一棵新的子树

int maxDD = 1;

head *tempPtr = heads[toId];

while (tempPtr)

{

int toIdd = tempPtr->toId;

if (toIdd != id)

{

if (tempPtr->maxDepth + 1 > maxDD)

maxDD = tempPtr->maxDepth + 1;

}

tempPtr = tempPtr->next;

}

curPtr->maxDepth = maxDD;

if (maxDD > maxD) maxD = maxDD;

}

curPtr = curPtr->next;

}

//更新结果

if (maxD < minDepthVal)

{

minDepthVal = maxD;

num = 1;

res[0] = id;

}

else if (maxD == minDepthVal)

{

res[num++] = id;

}

//DFS

curPtr = heads[id];

while (curPtr)

{

int toId = curPtr->toId;

getDepth(toId);

curPtr = curPtr->next;

}

}

Этот алгоритм в основном использует список смежности для достижения построения графа и использует обход в ширину и динамическое программирование для достижения минимального радиуса поиска.Задача требует найти кратчайший путь от корня до листа, то есть минимальный радиус, который собственно и должен найти минимальную глубину остовного дерева.

Скриншот результатов эксперимента:

图片1.png