코딩/백준 문제 풀이

BOJ 17834 - 사자와 토끼

stonejjun 2020. 8. 17. 20:57

문제 링크 : https://www.acmicpc.net/problem/17834

문제 풀이

문제를 보자마자 홀짝성을 생각할 수 있다. 다시 말하자면 주어진 그래프를 2가지 색으로 칠할수 있는지를 물어보는 문제이다. 만약 주어진 그래프를 2가지 색으로 칠할 수 있다면, 두 동물의 시작 색깔이 다르면 영원히 잡을 수 없게 되기 때문이다. 

주어진 그래프를 두 가지 색으로 칠할 수 있는지를 확인해 보자. 이는 dfs 한 번으로 쉽게 확인할 수 있다. dfs를 기본적으로 돌면서 두 가지 색을 번갈아가면서 칠해준다.  dfs를 돌 다 보면 이미 방문한 정점을 거를때가 있는데, 거르기 전에 현재 정점과 다른 색으로 칠해져 있는지를 확인해주면 된다. 만약 같은 색이라면 두 가지 색으로 칠할 수 없는 그래프이다. 하지만, 그러한 상황이 나오지 않는다면 두 가지 색으로 칠할 수 있는 그래프이다.

그래프를 빨간색과 파란색으로 칠했다고 하자. 두 동물이 서로 다른 색에서 출발하면 둘은 계속 다른색의 칸에 있게 되고, 따라서 잡을 수 없다. 따라서 게임이 끝나지 않는 경우는 두 동물이 서로 다른 색에서 출발하는 경우이며 이때의 경우의 수는 빨간색의 수*파란색의 수*2가 된다.

코드

 

 

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
 
ll arr[1010101];
vector<ll> v[1010101];
ll vis[1010101];
 
ll cnt1,cnt2,mang;
 
void dfs(ll x){
    for(auto k:v[x]){
        if(vis[k]==0){
            vis[k]=3-vis[x];
            if(vis[k]==1) cnt1++;
            else cnt2++;
            dfs(k);
        }
        else if(vis[k]==vis[x]){
            mang=1;
            return;
        }
    }
}
 
int main(){
    ll i,j,k,l,m,n;
    scanf("%lld %lld",&n,&m);
    while(m--){
        ll a,b;
        scanf("%lld %lld",&a,&b);
        v[a].push_back(b);
        v[b].push_back(a);
    }
 
    for(i=1;i<=n;i++){
        if(vis[i]) continue;
        cnt1++;
        vis[i]=1;
        dfs(i);
    }
 
    if(mang) printf("0");
    else printf("%lld",2*cnt1*cnt2);
}
cs

'코딩 > 백준 문제 풀이' 카테고리의 다른 글

문자열 구현 연습  (0) 2020.09.01
BOJ 1028 - 다이아몬드 광산  (0) 2020.08.18
BOJ 2924 - 천재  (0) 2020.08.17
BOJ 15907 - Acka의 리듬 세상  (0) 2020.08.06
BOJ 15311 - 약팔기  (2) 2020.08.03