알고리즘 문제해결/BOJ

BOJ 5859 Liars and Truth Tellers

havana723 2022. 8. 2. 16:36

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

 

5859번: Liars and Truth Tellers

After spending so much time around his cows, Farmer John has started to understand their language. Moreover, he notices that among his N cows (2 <= N <= 1000), some always tell the truth while others always lie. FJ carefully listens to M statements (1 <= M

www.acmicpc.net

 

문제를 잘 보면 쿼리가 T일 경우 두 소 모두 진실을 말하거나 거짓을 말하고 있고 쿼리가 F일 경우 한 소는 진실을, 한 소는 거짓을 말하고 있습니다. 따라서 T일 경우 두 정점이 같은 그룹에 속해야 하고 F일 경우 두 정점이 다른 그룹에 속해야 합니다.

 

이를 구하기 위해 SAT의 아이디어를 빌렸습니다. 소 $A$가 진실을 말하는 경우를 정점 $A$, 거짓을 말하는 경우를 정점 $A+N$으로 두면 총 $2N$개의 정점이 생기게 됩니다. 그리고 두 정점이 모두 진실이거나 모두 거짓이어야 하는 경우끼리 묶어 간선으로 연결해줍니다. 소 $u$와 $v$에 대해 쿼리가 T라면 정점 $u$와 $v$가 이어지고 정점 $u+N$과 $v+N$이 이어지는 식입니다. 반대로 쿼리가 F라면 정점 $u$와 $v+N$이 이어지고 정점 $u+N$과 $v$가 이어집니다.

 

이 때 특정 쿼리를 수행한 이후 어떤 소 $i$에 대하여 정점 $i$와 정점 $i+N$가 연결되어 있는 경우 모순이 발생하기 때문에 해당 쿼리 이전까지가 답이 됩니다.

 

아래는 코드입니다.

 

#include <bits/stdc++.h>
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
#define ends ' '

std::vector<int> UF;

void UF_init(int sz)
{
    UF.resize(sz + 1);
    for (int i = 1; i < UF.size(); i++)
        UF[i] = i;
}

int Find(int x)
{
    if (UF[x] == x) return x;
    else return UF[x] = Find(UF[x]);
}

void Union(int x, int y)
{
    x = Find(x);
    y = Find(y);
    UF[y] = x;
}

using namespace std;

int T, n, m;

int32_t main(void) {
  FastIO;
  T = 1;
  //cin >> T;

  while (T--) {
    cin >> n >> m;

        UF_init(2 * n);

        int ans = 0;

        for (int i = 0; i < m; i++) {
            int a, b;
            char c;
            cin >> a >> b >> c;

            if (c == 'T') {
                Union(a, b);
                Union(a + n, b + n);
            }
            else {
                Union(a, b + n);
                Union(a + n, b);
            }

            if (Find(a) == Find(a + n) || Find(b) == Find(b + n)) break;

            ans = i + 1;
        }

        cout << ans << endl;
  }

  return 0;
}

'알고리즘 문제해결 > BOJ' 카테고리의 다른 글

BOJ 5502 팰린드롬  (0) 2022.08.04
BOJ 8872 빌라봉  (0) 2022.08.03
BOJ 1635 1 또는 -1  (0) 2022.08.01
BOJ 16939 2×2×2 큐브  (0) 2022.07.31
BOJ 3056 007  (0) 2022.07.29