티스토리 뷰
문제
https://www.acmicpc.net/problem/3648
알고리즘
2-SAT
풀이
문제에서 2-SAT의 느낌을 물씬 풍기는 문장이 몇 있습니다. '적어도 하나'라는 문장은 OR을 연상케 하고 OR은 2-CNF에서 하나의 절을 구성합니다. 그리고 한 참가자에 대해 두 가지 선택을 할 수 있다는 점도 True와 False로 연관 지을 수 있으니 2-SAT으로 문제를 접근합시다.
심사위원의 의심 없이 다음라운드를 구성할 수 있다면 하나의 참가자에 대해 모순이 되는 경우가 없다는 의미와 같습니다. 즉, 각 정점의 True와 False의 sccid가 일치해서는 안됩니다.
상근이가 진출하는 경우는 그래프상에서 상근이의 False 정점이 True 정점보다 위상정렬상 빠른지 확인하면 됩니다.
이전 문제에서 위상정렬상 빠른 정점을 False로 평가하는 것이 True로 평가하는 것보다 항상 이득임을 확인했습니다.
코드
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;++i)
#define REP(i,n) for(int i=1;i<=n;++i)
#define FAST cin.tie(NULL);cout.tie(NULL); ios::sync_with_stdio(false)
using namespace std;
#define T(x) (x<<1)
#define F(x) (x<<1|1)
int n, m, a, b, VC, SC;
vector<vector<int>> adj;
vector<int> discovered, sccid;
stack<int> st;
int scc(int here) {
    int ret = discovered[here] = VC++;
    st.emplace(here);
    for (auto there : adj[here]) {
        if (discovered[there] == -1) ret = min(ret, scc(there));
        else if (sccid[there] == -1) ret = min(ret, discovered[there]);
    }
    if (ret == discovered[here]) {
        while (1) {
            int t = st.top();
            st.pop();
            sccid[t] = SC;
            if (t == here) break;
        }
        SC++;
    }
    return ret;
}
void OR(int A, int B) {
    adj[A ^ 1].emplace_back(B);
    adj[B ^ 1].emplace_back(A);
}
int main() {
    FAST;
    while (cin >> n >> m) {
        VC = SC = 0;
        adj.clear();
        adj.resize(n << 1);
        discovered.clear();
        sccid.clear();
        discovered = sccid = vector<int>(n << 1, -1);
        while (m--) {
            cin >> a >> b;
            a = a > 0 ? T(a - 1) : F(~a);
            b = b > 0 ? T(b - 1) : F(~b);
            OR(a, b);
        }
        rep(i, n << 1) if (discovered[i] == -1) scc(i);
        bool flag = true;
        for (int i = 0;i < n;++i) if (sccid[i] == sccid[i ^ 1]) {
            flag = false;
            break;
        }
        if (sccid[0] > sccid[1]) flag = false;
        cout << (flag ? "yes" : "no") << '\n';
    }
    return 0;
}'Algorithm' 카테고리의 다른 글
| [백준 16915] 호텔 관리 (0) | 2020.08.14 | 
|---|---|
| [백준 15675] 괴도 강산 (0) | 2020.08.13 | 
| [백준 11281] 2-SAT - 4 (0) | 2020.08.10 | 
| [백준 11280] 2-SAT -3 (0) | 2020.08.09 | 
| [백준 15483] 최소 편집 (0) | 2020.08.06 | 
										공지사항
										
								
							
								
								
									최근에 올라온 글
									
							
								
								
									최근에 달린 댓글
									
							
								
								- Total
 
- Today
 
- Yesterday
 
									링크
									
								
							
								
								
									TAG
									
							
								
								- union find
 - dfs
 - 이분탐색
 - Segment tree
 - sorting
 - kmp
 - Suffix Array
 - spring
 - 트라이
 - 이분매칭
 - implementation
 - sweeping
 - 2-SAT
 - 정렬
 - 펜윅트리
 - spring boot
 - 세그먼트트리
 - Fenwick
 - DP
 - bfs
 - 스위핑
 - greedy
 - dijkstra
 - string
 - 동적계획법
 - hld
 - SCC
 - 좌표압축
 - Oracle
 - knapsack
 
| 일 | 월 | 화 | 수 | 목 | 금 | 토 | 
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 
| 9 | 10 | 11 | 12 | 13 | 14 | 15 | 
| 16 | 17 | 18 | 19 | 20 | 21 | 22 | 
| 23 | 24 | 25 | 26 | 27 | 28 | 29 | 
| 30 | 
									글 보관함
									
							
					