树查询算法无法通过测试用例

时间:2020-07-11 18:50:10

标签: c++ algorithm data-structures graph-algorithm segment-tree

树是一个简单的图形,其中每两个顶点通过一条路径连接在一起。您将得到一棵有顶点的有根树,并且在树的每个顶点上都放置一盏灯。

系统会为您提供以下两种类型的查询:

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

关闭节点中的灯后的树 显然,现在顶点的答案是

enter image description here

代码:

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. switchesSubTree存储为该子树打开的灯的数量。

步骤:

 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.

但是对于某些测试用例,解决方案给出了超过时间限制的情况,对于某些测试用例也给出了错误的结果。 我在哪里做错了,什么是有效且更好的解决方案?

0 个答案:

没有答案