Алгоритм запроса дерева не проходит тестовые случаи - PullRequest
0 голосов
/ 11 июля 2020

Дерево - это простой граф, в котором каждые две вершины соединены ровно одним путем. Вам дано корневое дерево с вершинами, и лампа помещается в каждую вершину дерева.

Вам даются запросы следующих двух типов:

1 v: You switch the lamp placed on the vertex v, that is, either from On to Off or Off to On.
2 v: Determine the number of vertices connected to the subtree of v if you only consider the lamps that are in On state. In other words, determine the number of vertices in the subtree of v , such as u, that can reach from v by using only the vertices that have lamps in the On state.

Примечание: изначально все лампы включаются, и дерево основывается на номере вершины.

Формат ввода

Первая строка: два целых числа, обозначающие количество вершин и запросов Следующие строки: два числа и обозначающие ребро между вершинами и Следующими строками: два целых числа и, где - тип запроса. Примечание. Гарантируется, что эти ребра образуют дерево с корнем из вершины.

Формат вывода Для каждого запроса типа 2 выведите ответ в одной строке.

Ограничения

SAMPLE INPUT 
5 4
1 2
2 3
1 4
4 5
1 3
2 2
1 3
2 2
SAMPLE OUTPUT 
1
2

Пояснение:

Это дерево в первую очередь:

enter image description here

The tree after turning off lamp in node Obviously the answer now for vertex is

введите описание изображения здесь

Код:

void updateSubSwitches(vector<vector<int>> &tree,vector<int> &parent, vector<int> &switchesSubTree, int vertex, bool flag) {
    if(flag) {
        switchesSubTree[vertex]=1;
        for(int i=0;i<tree[vertex].size();i++) {
            switchesSubTree[vertex] += switchesSubTree[tree[vertex][i]];
        }
        int parentVertex=parent[vertex];
        while(switchesSubTree[parentVertex]!=0 && parentVertex!=0) {
            switchesSubTree[parentVertex]=switchesSubTree[parentVertex]+switchesSubTree[vertex];
            parentVertex=parent[parentVertex];
        }
        if(parentVertex == 0) {
        switchesSubTree[0]=switchesSubTree[0]+switchesSubTree[vertex];
        }
    } else {
        int parentVertex=parent[vertex];
        while(switchesSubTree[parentVertex]!=0 && parentVertex!=0) {
            switchesSubTree[parentVertex]=switchesSubTree[parentVertex]-switchesSubTree[vertex];
            parentVertex=parent[parentVertex];
        }
        if(parentVertex == 0) {
        switchesSubTree[0]=switchesSubTree[0]-switchesSubTree[vertex];
        }
        switchesSubTree[vertex]=0;
    }
}
 
int initialSubSwitches(vector<vector<int>> &tree, vector<int> &switchesSubTree,int vertex) {
    if(switchesSubTree[vertex] == -1) { 
        if(tree[vertex].size() > 0) {
            switchesSubTree[vertex] = 1;
            //cout<<vertex<<endl;
        for(int i=0;i<tree[vertex].size();i++){
            
            switchesSubTree[vertex] += initialSubSwitches(tree,switchesSubTree,tree[vertex][i]);
            
            
        } 
        return switchesSubTree[vertex];
    } else {
        //cout<<vertex<<endl;
            switchesSubTree[vertex] = 1;
            return 1;
    }
        }
}
 
int main() {
    int n,q;
    cin>>n>>q;
    vector<vector<int>> tree(n);
    vector<bool> arr(n,true);
    vector<int> switchesSubTree(n,-1);
    vector<int> parent(n);
    for(int i=1;i<=n-1;i++) {
        int a,b;
        cin>>a>>b;
        tree[a-1].push_back(b-1);
        parent[b-1] = a-1;
    }
    
    initialSubSwitches(tree,switchesSubTree,0);

 
    for(int i=1;i<=q;i++) {
        int b,v;
        cin>>b>>v;
        if(b==1) {
            arr[v-1]=!arr[v-1];
            updateSubSwitches(tree,parent,switchesSubTree,v-1,arr[v-1]);
        } else {
            cout<<switchesSubTree[v-1]<<endl;
        }
    }
}

Алгоритм:

Инициализация

  1. дерево хранит график
  2. arr хранит если лампа в вершине v включена или выключена.
  3. Switches SubTree хранит количество включенных ламп для этого поддерева.

Шаги:

 1. initialize the switchesSubTree array if initially all lamps are ON.
    2. For each query, 
     2.1 if lamp is turned OFF:
           decrease its ancestors by switchesSubTree[vertex] until we get a node whose lamp is OFF or we reach root vertex
           make switchesSubTree[vertex] = 0
     2.2 if lamp is turned ON:
           calculate no. of lamps swithced ON for this vertex which is 
             switchesSubTree[vertex] = 1 + sum(all lamps of children)
           increase the lamps for ancestors until we get a node whose lamp is OFF or we reach root vertex.

Но решение дает ПРЕВЫШЕНИЕ ВРЕМЕНИ для некоторых тестовых случаев, а также неверно для некоторых тестовых случаев. В чем я ошибаюсь и что может быть более эффективным и лучшим решением?

...