С Новым годом! Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
10 / 11 / 2
Регистрация: 10.07.2018
Сообщений: 70
Записей в блоге: 1
1

Избавиться от рекурсии

06.08.2018, 01:38. Показов 2226. Ответов 15

Author24 — интернет-сервис помощи студентам
Здравствуйте. У меня имеется рекурсивный метод:
Java
1
2
3
4
5
6
7
8
9
10
11
12
    static void dfs(int v, int last){
        if(g[v]) return;
        g[v] = true;
        d[v] = d[last]+1;
        if(d[v]>max){
            max=d[v];
            maxInd = v;
        }
        for(int u:graph[v]){
            dfs(u, v);
        }
    }
На acmp решение с применением этого метода получет ML, думаю, что чтоб избежать этого, нужно избавиться от рекурсии.
Как это сделать для данного метода? У меня не очень-то получается
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.08.2018, 01:38
Ответы с готовыми решениями:

Избавиться от рекурсии
Нужно в данной процедуре избавиться от рекурсии. Не могу понять как это сделать. masreal -...

Избавиться от рекурсии
Каким способом лучше всего избавиться от рекурсии ?

Избавиться от одной рекурсии
Всем доброго времени суток. Вот код программы (* N - целочисленный параметр *) load...

Избавиться от повтора вариантов при рекурсии
#include <stdio.h> void find (int *s ,int n) { int max = (n-1)/3; for (int b = 1;...

15
Эксперт Java
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
06.08.2018, 05:41 2
На acmp решение с применением этого метода получет ML,
Чо?
0
2711 / 2024 / 502
Регистрация: 17.02.2014
Сообщений: 9,417
06.08.2018, 08:57 3
Цитата Сообщение от ManyGames Посмотреть сообщение
решение
чего решаешь то? что есть свое решение - это хорошо, но условие всей задачи приведи.
0
10 / 11 / 2
Регистрация: 10.07.2018
Сообщений: 70
Записей в блоге: 1
06.08.2018, 10:10  [ТС] 4
Цитата Сообщение от xoraxax Посмотреть сообщение
На acmp решение с применением этого метода получет ML,
Чо?
acmp - сайт с задачками
ML - Memory Limit Exceeded, превышение ограничений по памяти

Добавлено через 3 минуты
Вот задача на acmp:


И вот моё решение:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.io.*;
import java.util.*;
 
public class Test{
 
    static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static ArrayList<Integer> graph[];
    static int n, m, maxInd;
    static long d[], max;
    static boolean g[];
 
    public static void main(String[] args) throws IOException {
        n = nextInt(); m = nextInt();
        graph = new ArrayList[n];
        d = new long[n];
        g = new boolean[n];
        for(int i = 0;i<n; i++) //инициализация
            graph[i] = new ArrayList<>();
        for(int i = 1; i<n; i++){
            int tmp = nextInt()-1;
            graph[tmp].add(i);
            graph[i].add(tmp);
        }
 
        //Первый dfs
        d[0] = -1;
        dfs(0, 0);
        Arrays.fill(g, false);
        //Второй dfs
        d[0] = -1;
        long z = max+1;
        max=0;
        dfs(maxInd, 0);
        System.out.println(max+1+(z*2)*(m-1));
    }
 
    static int nextInt() throws IOException {
        in.nextToken();
        return (int)in.nval;
    }
 
    static void dfs(int v, int last){
        if(g[v]) return;
        g[v] = true;
        d[v] = d[last]+1;
        if(d[v]>max){
            max=d[v];
            maxInd = v;
        }
        for(int u:graph[v]){
            dfs(u, v);
        }
    }
}
На codeforces такое решение прошло полностью, ибо там лимит по памяти 512 МБ

Добавлено через 4 минуты
Цитата Сообщение от ManyGames Посмотреть сообщение
Вот задача на acmp:
Тут
0
2711 / 2024 / 502
Регистрация: 17.02.2014
Сообщений: 9,417
06.08.2018, 10:15 5
Цитата Сообщение от ManyGames Посмотреть сообщение
Вот задача
тебе нужна помощь, а мы должны ходить по ссылке!? Приведи текст задачи здесь.
0
10 / 11 / 2
Регистрация: 10.07.2018
Сообщений: 70
Записей в блоге: 1
06.08.2018, 10:21  [ТС] 6
Пробовал избавиться от рекурсии при помощи очереди вот так:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
static void dfs(int v, int last){
        LinkedList<Integer> qV = new LinkedList<>();
        LinkedList<Integer> qLast = new LinkedList<>();
        qV.offer(v);
        qLast.offer(last);
        while(!qV.isEmpty()){
            v = qV.pop();
            last = qLast.pop();
            if(g[v]) return;
            g[v] = true;
            d[v] = d[last]+1;
            if(d[v]>max){
                max=d[v];
                maxInd = v;
            }
            for(int u:graph[v]){
                if(!g[u]){
                    qV.offer(u);
                    qLast.offer(v);
                }
            }
        }
    }
Но все равно ML

Добавлено через 2 минуты
Цитата Сообщение от Aviz__ Посмотреть сообщение
тебе нужна помощь, а мы должны ходить по ссылке!? Приведи текст задачи здесь.
В лаборатории теоретической пиротехники изучают новые технологии организации фейерверков. Фейерверк представляется как корневое дерево, а поскольку в мощном фейерверке его элементы также взрываются, порождая новые фейерверки, то ученые вводят операцию возведения корневого дерева в степень.

Корневое дерево содержит одну или несколько вершин. Одна из вершин выделена и называется корнем дерева, для каждой из остальных вершин ровно одна другая вершина является родителем. При этом от любой вершины можно добраться до корня, последовательно переходя от вершины к ее родителю. Вершина, которая не является родителем никакой другой вершины, называется листом. Если вершина x является родителем вершины y, то вершина y является ребенком вершины x. Будем говорить, что вершина и ее родитель соединены ребром.
Фейерверк задается своим базовым деревом T и мощностью m. Фейерверк представляется деревом, которое получается в результате возведения дерева T в степень m. Операция возведения дерева в степень устроена следующим образом. Если m = 1, то результат T1 — само дерево T. Для m > 1 рассмотрим дерево Tm – 1. Выполним следующую операцию: для каждого листа x дерева Tm – 1 создадим копию дерева T и назначим лист x родителем корня соответствующей копии. Получившееся дерево будет деревом Tm.
Путем в дереве называется последовательность вершин, в которой две соседние вершины соединены ребром. Все вершины в пути должны быть различны.
Для того, чтобы оценить красоту фейерверка, необходимо определить, какое максимальное количество вершин может содержать путь в дереве, которым представляется фейерверк
Требуется написать программу, которая по описанию дерева T и натуральному числу m определяет красоту фейерверка с базовым деревом T и мощностью m.

Входные данные
Первая строка входного файла INPUT.TXT содержит два натуральных числа n и m – количество вершин в базовом дереве фейерверка T и его мощность (3 ≤ n ≤ 200 000, 1 ≤ m ≤ 200 000).
Вторая строка описывает дерево T и содержит (n – 1) целых чисел: p2, p3, …, pn – номера родителей вершин 2, 3, …, n, соответственно (1 ≤ pi ≤ i – 1).
Выходные данные
В выходной файл OUTPUT.TXT выведите одно целое число – красоту фейерверка, представляемого деревом Tm.

Пример:
Ввод:
4 2
1 1 2
Вывод:
10
0
2711 / 2024 / 502
Регистрация: 17.02.2014
Сообщений: 9,417
06.08.2018, 11:49 7
а базовое дерево с числом узлов 5, какой вид должно иметь?
вид 1:
-------1
-----2---3
----4
---5
или вид 2:
-------1
-----2---3
---4------5
Вид 2, в плане красоты, при умножении, на мой взгляд, лучше.
И почему нужно без рекурсии?
Если, скажем, любое дерево растет, по виду 1, то при умножении, все проще))
0
10 / 11 / 2
Регистрация: 10.07.2018
Сообщений: 70
Записей в блоге: 1
06.08.2018, 13:51  [ТС] 8
Цитата Сообщение от Aviz__ Посмотреть сообщение
а базовое дерево с числом узлов 5, какой вид должно иметь?
Базовое дерево нельзя строить произвольно, зависит от входных данных. Например, входные данные такие
5 2
1 1 3 3
То базовое дерево выглядит так:
------1
---2----3
------4---5
Я решаю так: храню граф в списке смежности graph и выполняю поиск диаметра дерева.
Для данного примера список смежности выглядит так:
1) 2, 3
2) -
3) 4, 5
4) -
5) -
Но, для того чтоб выполнить второй обход в глубину, храню его как неориентированный граф.
Сначала запускаю первый dfs от первой вершины и ищу самую удаленную, в примере самая удаленная - 5. Запоминаю расстояние до неё в переменную z(3). Потом от самой удаленной вершины запускаю ещё раз dfs, в примере от пятой вершины самая удаленная - вторая, расстояние до неё - 4. А далее по формуле ans = max+(z*2)*(m-1) (где max - диаметр дерева, z - расстояние от первой вершины до самой удаленной, m - из условия) вывожу ответ. В примере z = 3, max = 4. ans = 4+(3*2)*(2-1) = 4+6 = 10

На codeforces, повторюсь, такое решение прошло, а на acmp нет - ML. Но на codeforces по памяти ограничение в 512 Мб, а на acmp - всего 16.

Добавлено через 4 минуты
То есть я рассматриваю только базовое дерево, а ответ высчитываю по формуле
0
2711 / 2024 / 502
Регистрация: 17.02.2014
Сообщений: 9,417
06.08.2018, 13:54 9
так чем тебе рекурсия не мила?
0
10 / 11 / 2
Регистрация: 10.07.2018
Сообщений: 70
Записей в блоге: 1
06.08.2018, 13:56  [ТС] 10
Цитата Сообщение от ManyGames Посмотреть сообщение
На acmp решение с применением этого метода получет ML, думаю, что чтоб избежать этого, нужно избавиться от рекурсии.
Цитата Сообщение от Aviz__ Посмотреть сообщение
так чем тебе рекурсия не мила?
Вероятно, стек при работе моего решения занимает много памяти, из-за этого решение не проходит
Но может я и ошибаюсь
0
2711 / 2024 / 502
Регистрация: 17.02.2014
Сообщений: 9,417
06.08.2018, 14:00 11
Цитата Сообщение от ManyGames Посмотреть сообщение
Вероятно
оптимизируй рекурсивный метод))
0
10 / 11 / 2
Регистрация: 10.07.2018
Сообщений: 70
Записей в блоге: 1
06.08.2018, 14:11  [ТС] 12
Там, где 205 Мб - рекурсивный dfs, а там, где 36 Мб - без рекурсии (метод, который я писал выше).
Вы все ещё думаете, что рекурсивный метод можно оптимизировать?)
Миниатюры
Избавиться от рекурсии  
0
2711 / 2024 / 502
Регистрация: 17.02.2014
Сообщений: 9,417
06.08.2018, 14:17 13
надеюсь, это поможет понять где у твоего рекурс метода засада https://www.cyberforum.ru/java/thread2250765.html - дебагер
0
10 / 11 / 2
Регистрация: 10.07.2018
Сообщений: 70
Записей в блоге: 1
06.08.2018, 14:37  [ТС] 14
Засада?.. Алгоритм я вычитал в книге Антти Лааксонена "Олимпиадное программирование", им же и воспользовался. Не думаю, что спортивный программист такого высокого уровня может издать книгу, в которой некоторые алгоритмы "с засадами".
0
2711 / 2024 / 502
Регистрация: 17.02.2014
Сообщений: 9,417
06.08.2018, 14:42 15
ManyGames, Ок! Удачи)). Когда на авторитетов перестанешь кивать, продолжим...
1
1 / 1 / 0
Регистрация: 28.07.2016
Сообщений: 9
28.11.2018, 17:10 16
Твое решение неправильно работает. Контрпример:
4 2
1 2 3
Ответ:8, а у тебя 12.
1
28.11.2018, 17:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.11.2018, 17:10
Помогаю со студенческими работами здесь

Задача о расстановке n ферзей на доске n на n: как избавиться от рекурсии?
Помогите упростить данный код. Что бы было все в одной функции #include&lt;iostream&gt; #include...

Как избавиться от переполнения стека при глубокой рекурсии?
Добрый день, Я написала рекурсивную функцию которая считает сложение дробей при n = 1000...

Рекурсии
Подскажите, в каком месте я ошибся, сижу, думаю и не понимаю, как правильно доделать программу С...

Рекурсии
Ребят,программа по задаче 22 из ЕГЭ. При вводе программа зависает. #include &lt;stdio.h&gt; int...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru