Doby's Lab

백준 14675번: 단절점과 단절선 (C++) 본문

PS/BOJ

백준 14675번: 단절점과 단절선 (C++)

도비(Doby) 2022. 6. 1. 23:34

https://www.acmicpc.net/problem/14675

 

14675번: 단절점과 단절선

프로그램의 입력은 표준 입력으로 받는다. 입력의 첫 줄에는 트리의 정점 개수 N이 주어진다. (2 ≤ N ≤ 100,000) 트리의 정점은 1번부터 n번까지 존재한다. 다음 줄부터 N-1개의 줄에 걸쳐 간선의 정

www.acmicpc.net


Solved By: Articulation

 

방금 공부한 Articulation Point와 Edge를 사용해보았습니다.

#include <iostream>
#include <vector>
#include <set>
#include <memory.h>
#define MAX 100001
using namespace std;

int n, q;
vector<int> adj[MAX];
bool isCut[MAX];
int visitedOrder[MAX];
int order = 0;
set<pair<int, int>> cutEdge;
vector<pair<int, int>> edges;

int dfsPoint(int now, bool isRoot){
    int minOrder = visitedOrder[now] = ++order;
    int child = 0;
    
    for(int i = 0; i < adj[now].size(); i++){
        int next = adj[now][i];
        
        if(visitedOrder[next]){
            minOrder = min(minOrder, visitedOrder[next]);
            continue;
        }
        
        child++;
        int childOrder = dfsPoint(next, false);
        
        if(!isRoot && visitedOrder[now] <= childOrder){
            isCut[now] = true;
        }
        
        minOrder = min(minOrder, childOrder);
    }
    
    if(isRoot){
        isCut[now] = (child >= 2);
    }
    
    return minOrder;
}

int dfsEdge(int now, int par){
    int minOrder = visitedOrder[now] = ++order;
    
    for(int i = 0; i < adj[now].size(); i++){
        int next = adj[now][i];
        
        if(next == par) continue;
        
        if(visitedOrder[next]){
            minOrder = min(minOrder, visitedOrder[next]);
            continue;
        }
        
        int childOrder = dfsEdge(next, now);
        
        if(childOrder > visitedOrder[now]){
            cutEdge.insert({now, next});
            cutEdge.insert({next, now});
        }
        
        minOrder = min(minOrder, childOrder);
    }
    
    return minOrder;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    cin >> n;
    for(int i = 0; i < n - 1; i++){
        int a, b; cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
        edges.push_back({a, b});
    }
    
    dfsPoint(1, true);
    order = 0;
    memset(visitedOrder, 0, sizeof(visitedOrder));
    dfsEdge(1, 0);
    
    cin >> q;
    for(int i = 0; i < q; i++){
        int Q; cin >> Q;
        if(Q == 1){
            int k; cin >> k;
            if(isCut[k]) cout << "yes";
            else cout << "no";
        }
        else{
            int k; cin >> k;
            if(cutEdge.count(edges[k - 1]) == 1){
                cout << "yes";
            }
            else cout << "no";
        }
        
        cout << '\n';
    }
    
    return 0;
}

 

728x90

'PS > BOJ' 카테고리의 다른 글

백준 15480번: LCA와 쿼리 (C++)  (0) 2022.06.04
백준 23355번: 공사 (C++)  (0) 2022.06.03
백준 11400번: 단절선 (C++)  (0) 2022.06.01
백준 11266번: 단절점 (C++)  (0) 2022.06.01
백준 3640번: 제독 (C++)  (0) 2022.06.01