DFS의 시작시간, 종료시간

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2615

m개의 쿼리가 들어 온다. a,b 쿼리는 b가 a의 서브트리에 속하는가?
쿼리가 많으므로 한 쿼리를 O(1)로 처리해야 한다.
DFS로 각 노드의 DFS 시작시간과 종료시간을 기록해두면 저 쿼리를 O(1)로 처리 할 수 있다. 각각의 시작시간을 Start, 종료시간을 Finish라 하면
Start(a) < Start(b) and Finish(b) < Finish(a) 이면 b는 a의 서브트리이다.

#include <bits/stdc++.h>
using namespace std;
int n,m;
vector< vector<int> > adj;
vector<int> start;
vector<int> finish;
int main()
{
    int t;
    scanf("%d",&t);
    for(int tc=1;tc<=t;++tc){
        scanf("%d",&n);
        int cnt = 0;
        int curtime = 0;
        adj.clear();
        for(int i=0;i<n;++i){
            adj.push_back(vector<int>());
            int x;
            scanf("%d",&x);
            for(int j=0;j<x;++j){
                adj[i].push_back(++cnt);
            }
        }
        start = vector<int>(cnt+1,0);
        finish = vector<int>(cnt+1,0);
        stack<pair<int, int> > stk;
        stk.push(make_pair(0,0));
        while(!stk.empty()){
            int cur = stk.top().first;
            int idx = stk.top().second;
            if(idx==0)start[cur] = ++curtime;
            if(cur<n){
                if(idx<adj[cur].size()){
                    stk.top().second = idx + 1;
                    stk.push(make_pair(adj[cur][idx],0));
                    continue;
                }
            }
            finish[cur] = ++curtime;
            stk.pop();
        }
        scanf("%d",&m);
        printf("Case %d:\n",tc);
        for(int i=0;i<m;++i){
            int a,b;
            scanf("%d%d",&a,&b);
            puts(start[a]<start[b] && finish[b]<finish[a]?"Yes":"No");
        }
        if(tc!=t)puts("");
    }
}

댓글

이 블로그의 인기 게시물

BOJ 11478 - 서로 다른 부분 문자열의 개수

Union-Find, Disjoint Set