PS

BOJ 19538 - 루머

728x90

www.acmicpc.net/problem/19538

 

19538번: 루머

예제 1 0분 : 최초 유포자($1$, $6$번 사람)가 루머를 생성한다. 1분 : $1$번 사람은 $2$, $3$번 사람에게 루머를 퍼뜨린다. $2$번 사람은 주변인 $2$명 중 $1$명이 루머를 믿고 있어 루머를 믿게 된다. $3$

www.acmicpc.net

 

이 문제는 시간 제한이 10초 이며, BFS 로 순회하면서 이중 포문을 돌리더라도 시간초과가 나지 않는다

 

루머 최초 유포자는 0의 값을 갖도록 초기화 시키고 나머지는 전부 -1 을 갖게 만든다

BFS 로 순회할 것이므로 초기화 작업시에 큐에 미리 최초 유포자 정보를 넣는다.

 

큐를 돌면서 현재 노드를 기준으로 인접한 다음 노드가 있는지 찾기위해 반복문을 실행한다

 

인접한 다음 노드가 -1 의 값을 갖고 있으면, 그 노드는 아직 루머가 유포되지 않은 노드이므로

그 다음노드를 기준으로 다른 인접한 노드들을 찾는다. 

찾으면서 인접한 노드들 중 루머를 이미 믿고 있는 사람들이 있다면 찾아내어 갯수를 센다

 

절반이상이 믿고 있으면 갱신하고 아니면 다음 차례로 넘어간다.

 

 

- C++

#include <cstring>
#include <iostream>
#include <queue>
#include <vector> 
 
#define MAX 200001 
 
using namespace std;
 
int N, M; // 사람수, 최초 유포자 수 
vector<int> adj[MAX]; // 인접행렬 
int rumor[MAX]; // 루머 믿는 시간 
queue<pair<intint>> q; // 노드 번호, 시간 
 
void solve() {
    while(!q.empty()) {
        int node = q.front().first;
        int time = q.front().second;
        q.pop();
        
        for (auto next_node : adj[node]) {
            if (rumor[next_node] == -1) { // 최초 유포자가 아닌 경우 
                int cnt = 0// 인접한 대상 중 루머 믿는 사람 몇명인지 갯수 세기 
                
                for (auto next_next_node : adj[next_node]) {
                    if (~rumor[next_next_node] && rumor[next_next_node] <= time) cnt += 1;
                }
                
                int next_node_size = adj[next_node].size(); // 다음 노드의 전체 인접한 노드 수 중에서 
                int half = next_node_size / 2// 절반을 추려냄 
                
                if (next_node_size % 2 == 1) half += 1// 다만 홀수 일땐 짝홀 맞춰야하고 
                
                if (cnt >= half) { // 절반이상이 믿고 있으면 갱신 
                    rumor[next_node] = time + 1;
                    q.push({next_node, time + 1});
                }
            }
        }
    }
}
 
int main() {
    cin.tie(0); ios_base::sync_with_stdio(0);
    
    cin >> N;
    
    int num;
    for (int i = 1; i <= N; ++i) {
        while(1) {
            cin >> num;
            if (num == 0break;
            adj[i].push_back(num);
        }
    }
    
    memset(rumor, -1sizeof(rumor));
    
    cin >> M;
    
    for (int i = 0; i < M; ++i) {
        cin >> num;
        rumor[num] = 0;
        q.push({num, 0});
    }
    
    solve();
    
    for (int i = 1; i <= N; ++i) cout << rumor[i] << " ";
    
    return 0;
cs

 

728x90

'PS' 카테고리의 다른 글

BOJ 2661 - 좋은 수열  (0) 2021.03.12
BOJ 3114 - 사과와 바나나  (0) 2021.03.12
BOJ 7579 - 앱  (0) 2021.03.10
BOJ 1943 - 동전 분배  (0) 2021.03.09
BOJ 1199 - 오일러 회로  (0) 2021.03.05