Codeforces Round #498 (Div. 3) E. Military Problem (DFS)

  • 题意:建一颗以\(1\)为根结点的树,询问\(q\)次,每次询问一个结点,问该结点的第\(k\)个子结点,如果不存在则输出\(-1\).

  • 题解:该题数据范围较大,需要采用dfs预处理的方法,我们从结点\(1\)开始向下找,\(ans\)数组记录的是,第\(x\)次查找时的结点,\(path\)表示某个结点所需的查找次数,\(siz\)数组表示某个结点的子结点个数.之后每次询问时,判断一下情况是否成立,如果成立,先找出该结点所对应的查找次数(\(path[u]\)),向下找第\(k\)个子结点即可.

  • 代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <unordered_set>
    #include <unordered_map>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
     
    int n,q;
    int x;
    int u,k;
    vector<int> v[N];
    int cnt=1;
    int ans[N];
    int path[N];
    int siz[N];
     
     
    void dfs(int node){
        ans[cnt]=node;
        path[node]=cnt++;
        siz[node]=1;
        for(auto w:v[node]){
            dfs(w);
            siz[node]+=siz[w];
        }
    }
     
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);
        cin>>n>>q;
         for(int i=2;i<=n;++i){
             cin>>x;
             v[x].pb(i);
         }
         dfs(1);
         for(int i=1;i<=q;++i){
             cin>>u>>k;
             if(siz[u]<k) puts("-1");
             else printf("%d\n",ans[path[u]+k-1]);
         }
     
        return 0;
    }
    
原文地址:https://www.cnblogs.com/lr599909928/p/13045448.html