Удаление в дереве, но только какой-то узел

https://i.stack.imgur.com/JAz2M.png

это проблема. Я написал код. но почему-то не смог пройти все тесты. Все тестовые примеры, которые я создал, верны. Можете ли вы сказать мне, почему я понимаю это неправильно?

Вам дано дерево каталогов из N каталогов/папок. Каждый каталог представлен отдельным номером в диапазоне от 1 до N. Идентификатор корневого каталога равен 1, затем у него есть несколько дочерних каталогов, эти каталоги могут содержать некоторые другие, и так далее. Теперь вам дан список идентификаторов каталогов для удаления, вам нужно найти минимальное количество каталогов, которые необходимо удалить, чтобы все каталоги в данном списке были удалены.

vector<vector<int> > adj;
vector<bool> del;
vector<bool> col;
void Final(int a, bool val)
{
    col[a] = val;
    if (del[a])
        val = del[a];
    for (int i = 0; i < adj[a].size(); i++) {
        Final(adj[a][i], val);
    }
    return;
}
int main()
{
    int n;
    cin >> n;
    adj.resize(n + 1);
    adj.clear();
    for (int i = 1; i <= n; i++) {
        int a;
        cin >> a;
        adj[a].push_back(i);
    }
    int q;
    cin >> q;
    if (q <= 1) {
        cout << q << endl;
        return 0;
    }
    del.resize(n + 1);
    col.resize(n + 1);
    del.clear();
    col.clear();
    for (int i = 0; i <= n; i++) {
        col[i] = false;
        del[i] = false;
    }
    for (int i = 0; i < q; i++) {
        int a;
        cin >> a;
        del[a] = true;
    }
    if (del[1]) {
        cout << "1" << endl;
        return 0;
    }
    else {
        Final(1, false);
        int final = q;
        for (int i = 1; i <= n; i++) {
            if (del[i] && col[i])
                final--;
        }
        cout << final << " ";
    }
}

Если вы правильно отформатируете свой код (предпочтительно с помощью некоторых инструментов, встроенных в вашу IDE), вам очень поможет. Также полезно прочитать здесь: Как отлаживать небольшие программы

Yksisarvinen 07.04.2019 16:15

1) Я всегда голосую за закрытие вопросов вида "почему судья отклоняет этот код?", по нескольким причинам. 2) Вы не рассказали нам, что пробовали, что делает задачу помочь вам еще более утомительной. 3) Если вы умны, вы можете обмануть судью, чтобы он раскрыл случай ошибки; это хорошая головоломка, поэтому постарайтесь решить ее сами, и если вам это удастся, не портите ее другим.

Beta 07.04.2019 16:20

Вы правы. Но я пытаюсь с последних трех дней.

user10207601 07.04.2019 16:24
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
151
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

используйте ДФС!

Если корень помечен как «подлежащий удалению», верните 1, (это в лучшем случае, вы выполняете минимум работы). В противном случае выполните рекурсию по каждому дочернему элементу корня и сложите их, чтобы узнать количество удаляемых узлов. Инвариант: если узел должен быть удален, не используйте повторное использование поддерева дальше (поскольку все, что укоренено в этом поддереве, все равно исчезнет)

Вот какой-то псевдокод

DFS(root)
    if (root is to be deleted)
        return 1
    else 
        number_of_nodes_to_delete = 0;
        for every child c of root
            number_of_nodes_to_delete += DFS(c)
        return number_of_nodes_to_delete;

У вас явно правильная идея представить дерево в виде списка смежности vector<vector<int>>.

В качестве второстепенной детали передайте список смежности как const& в рекурсию. Это экономит время копирования. (DFS(int root, const vector<vector<int>>& adjList может быть полезной подписью функции).

Я решил то же самое, используя Java. Ниже приведен код.

// Function to add an edge into the graph
void addEdge(int v, int w) {
    adj[v].add( w); // Add w to v’s list.
}

 public int DFS(int s, Set<Integer> tset) {
   // Store the DFS travel which does not contain child nodes to be deleted
    List<Integer> dfs_travel = new Vector<>();
    // Initially mark all vertices as not visited
    List<Boolean> visited = new Vector<Boolean>(V);
    for (int i = 0; i <= V; i++)
        visited.add(false);

    // Create a stack for DFS
    Stack<Integer> stack = new Stack<>();

    // Push the current source node
    stack.push(s);

    while (stack.empty() == false) {
        // Pop a vertex from stack and print it
        s = stack.pop();

        // Stack may contain same vertex twice. So
        // we need to print the popped item only
        // if it is not visited.
        // Also check whether the element is part of elements to be remove
        if (visited.get(s) == false && tset.contains(s)) {
            dfs_travel.add(s);
            visited.set(s, true);
        }

        // Get all adjacent vertices of the popped vertex s
        // If a adjacent has not been visited, 
        // and it is not in delete set then push it
        // to the stack.
        if (!tset.contains(s)) {
            Iterator<Integer> itr = adj[s].iterator();
            while (itr.hasNext()) {
                int v = itr.next();
                if (!visited.get(v))
                    stack.push(v);
            }
        }
    }
    return dfs_travel.size();
}

private int processDirectoryDeletion(int n, int[] folders, int m,
        int[] idsTodelete) {
    TestClass g = new TestClass(n);

    Set<Integer> tset = new HashSet<Integer>();
    for (int i = 0; i < idsTodelete.length; i++) {
        tset.add(idsTodelete[i]);
    }
    g.addEdge(0, 1);
    int ans = 0;
    for (int i = 1; i < n; i++) {
        g.addEdge(folders[i], i + 1);
    }
    return g.DFS(1, tset);
  }

Другие вопросы по теме