PS

220901 문제 풀이 기록

2022. 9. 1. 23:34

G3 | 11562 - 백양로 브레이크

풀이 시간: 약 25분

시도 횟수: 2회

체감 난이도: G3

풀이 쓸 의향: 下

풀이

더보기

모든 노드에서 다른 모든 노드까지 다익스트라 돌리기. 플로이드-워셜도 됨.

여담: 그냥 문득 G3이 어느 정도 난이도였나 기억하려고 한번 풀어봄.

 

 

P5 | 20158 - 사장님 달려가고 있습니다

풀이 시간: 약 1시간 + 20분

시도 횟수: 무려!!! 14회

체감 난이도: 마음같아선 P4주고싶지만 내실수로 이렇게된거라 P5 하위권...

풀이 쓸 의향: 下

풀이

더보기

그냥 단순 BFS인데 구현량이 좀 많음

여담: 이틀 전에 풀다가 때려치고 다시 풀었다. 참 많은 곳에서 실수를 해버려서... ;(

달려가는 중간에 있는 구역도 장애물이 있으면 밟으면 안된다는 점에 주의할 것....

'PS > 풀이 기록장' 카테고리의 다른 글

220903 문제 풀이 기록  (0) 2022.09.04
220902 문제 풀이 기록  (0) 2022.09.04
220831 문제 풀이 기록  (0) 2022.08.31
220830 문제 풀이 기록  (0) 2022.08.30
220829 문제 풀이 기록  (0) 2022.08.29

220831 문제 풀이 기록

2022. 8. 31. 23:52

P4 | 10220 - Self Representing Seq

풀이 시간: 약 25분 + 10분

시도 횟수: 2회

체감 난이도: X

풀이 쓸 의향: 下

풀이

더보기

N<=3 이거나 N==6이면 0, N==4면 2, 나머진 모두 1 출력.

여담: 사실 N=1부터 N=16쯤까지 브루트 포스로 한번 다 해보니까 이상한 규칙이 보이길래 일단 때려박아보고 AC 맞은 뒤에 증명함...

태그에 "런타임 전의 전처리" 박으려다가 꾹 참고 그냥 뒀는데, 증명 후 풀이였으면 정말 P3 위로 올라가는 정신나간 난이도의 문제였을 것으로 추정됨.

 

 

사실 더 풀려고 했는데 문제 하나 잘못 읽고 삽질하는 바람에 나중에 푸는 걸로.... ;(

'PS > 풀이 기록장' 카테고리의 다른 글

220902 문제 풀이 기록  (0) 2022.09.04
220901 문제 풀이 기록  (0) 2022.09.01
220830 문제 풀이 기록  (0) 2022.08.30
220829 문제 풀이 기록  (0) 2022.08.29
220828 문제 풀이 기록  (0) 2022.08.28

220830 문제 풀이 기록

2022. 8. 30. 23:48

P4 | 1412 - 일방통행

풀이 시간: 약 40분

시도 횟수: 2회

체감 난이도: P4 최하위권

풀이 쓸 의향: 中

풀이

더보기

주어진 그래프에서 일방통행 도로들만 봤을 때, 사이클이 있으면 NO, 없으면 YES

여담: 이 아이디어가 굉장히 빨리 떠올라서 운 좋게 빠르게 풀 수 있었다. 만약 이 아이디어 상상이 안됐다면, 혹은 관찰 첫발을 잘못 밟았으면 충분히 높은 난이도라고 생각될 수 있겠다 싶다.

'PS > 풀이 기록장' 카테고리의 다른 글

220901 문제 풀이 기록  (0) 2022.09.01
220831 문제 풀이 기록  (0) 2022.08.31
220829 문제 풀이 기록  (0) 2022.08.29
220828 문제 풀이 기록  (0) 2022.08.28
220827 문제 풀이 기록  (0) 2022.08.27

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

 

10542번: 마피아 게임

초등학교에서도 중학교에서도 고등학교에서도 대학교에서도 소풍에서도 엠티에서도 낮이나 밤이나 봄이나 여름이나 가을이나 겨울이나 실내에서도 실외에서도 손쉽게 즐길 수 있는 마.피.아.

www.acmicpc.net

 

1. 문제

- $N$명의 사람들이 마피아 게임을 진행한다.

- 각 사람들이 마피아일것 같은 사람을 투표하게 되는데, 시민은 자신을 제외한 다른 사람 아무나 투표하고, 마피아는 시민 중 한 명에게 투표한다.

- 마피아일 수 있는 사람 수의 최대값을 출력하라.

 

2. 힌트

 

힌트 1

더보기

문제 자체만으로 풀기에는 너무 까다로우니, 일단 유향 그래프로 문제 상황을 정리해서 생각해 보자.

a가 b에게 투표했으면 a->b로 나타내는 방식으로 하면 문제 상황을 쉽게 정리할 수 있을 것이다.

 

힌트 2

더보기

사실 유향 그래프가 아니라 무향 그래프로도 충분히 문제를 해결할 수 있다.

a가 b에게 투표를 했건, b가 a에게 투표를 했건 두 사람이 동시에 마피아일 수는 없기 때문이다.

이제 문제가 "그래프에서 이웃하지 않은 정점들을 고르는 최대 개수를 구하시오" 로 바뀌었다.

 

힌트 3

더보기

만약 트리가 1-2-3 처럼 한 줄로 되어 있고, 1번, 2번 노드가 단말 노드라면 2번 노드를 고르는 것 보다는 1번 노드를 고르는 것이 반드시 최적이다.

이를 조금 확장해서 생각해 보자. 반드시 a를 고르는것보다 b를 고르는 경우가 더욱 이득인 경우는 어떤 경우일까?

 

 

3. 문제 관찰 과정 및 풀이

 

3-1. 문제 관찰 과정

문제를 처음 봤을 때, 솔직히 조금 어지러웠다. 문제 지문이 살짝 이해하기 힘든 점도 있기는 했지만, 그보다도 대체 문제 풀이를 어떻게 시작해야 할지 감도 안잡혔기 때문이다.

조금 생각하다 보니, 참가자의 투표를 유향 그래프로 나타내어 그래프를 직접 그려보면 문제 상황 자체를 쉽게 이해할 수 있다 생각이 들어 그림판을 켜서 예제 입력을 직접 그리며 관찰해 보았다.

 

"마피아는 서로 마피아를 투표하지 않는다" 라는 것은, 그래프가 a->b로 연결되어 있을 때 a번 사람이 마피아라면 b번 사람은 마피아일 수 없다는 것을 의미한다.

그런데, 어차피 a->b로 연결되어 a번 사람과 b번 사람이 동시에 마피아가 될 수 없다면 그래프를 유향 그래프로 그리는 것이 오히려 불편해지기 때문에, 무향 그래프로 바꾸어 생각해 보았다.

 

이렇게 무향 그래프로 바꾸고 나면 "서로 이웃하지 않는 노드들을 최대한 많이 선택할 때, 그 노드들의 개수를 구하여라" 라고 문제를 변환하여 생각할 수 있다.

처음에는 DP 문제일까 하고 고민해 보았는데, 어떻게 구현해도 시간 안에 예쁘게 구현될 것 같지 않아서 때려쳤다.

 

그렇게 계속 관찰하다가, "일단 반드시 골랐을 때 이득인 노드가 있을까?" 라는 생각으로 그래프를 살펴보았다.

가장 처음에는 연결된 개수가 가장 작은 것을 먼저 고르면 되는 그리디 문제인가 고민해 보았지만, 바로 반례를 찾아 폐기되었다.

그런데 반례를 만들다가 a->b->c로 일직선으로 (즉, 옆으로 새는 길 없이) 연결된 형태이며 a, b번 노드가 둘 다 단말 노드라면 b보다는 a를 고르는 것이 최적이라는 사실을 발견했다.

이를 조금 더 확장하여 문제를 해결해 보자.

 

3-2. 문제 풀이

각 정점을 사람의 번호, 간선은 서로가 투표했는지 여부에 따라 무향 그래프를 하나 생성한다.

그렇다면 문제가 "서로 이웃하지 않는 노드들을 최대한 많이 선택할 때, 그 노드들의 개수를 구하여라" 로 치환된다.

 

이 때, 반드시 단말 노드를 가장 먼저 고르는 것이 최적이라는 사실을 관찰을 통해 짐작할 수 있다.

이유는 간단한데, 단말 노드의 경우 간선이 단 하나만 연결되어 있으므로 해당 노드를 골랐을 때 고르지 못하게 되는 노드는 단 하나만 생긴다.

그런데 단말 노드 대신 고르지 못하게 되는 다른 노드를 고르게 되면 반드시 단말 노드를 고른 것보다 고를 수 있는 노드 수가 항상 같거나 적으므로, 단말 노드를 고르는 것이 더 최적해라는 것을 알 수 있다.

 

또한, 단말 노드가 존재하지 않을 때까지 노드를 고르면 나머지 그래프들은 전부 거대한 사이클 하나로 이루어진 그래프가 되는데, 사이클 하나로 이루어진 그래프에서는 반드시 (노드 개수 / 2) 만큼의 노드를 고를 수 있으니 각 사이클을 DFS로 돌며 크기를 확인하고 값을 더해주면 된다.

 

주의할 점은, 이 문제의 경우 그래프 하나가 아니라 끊어져 있는 서로 다른 여러 그래프가 나올 수 있으므로 사이클 크기 처리를 해 줄때 각 그래프에 대해 한 번씩 전부 돌며 연산해주어야 한다.

 

4. 코드

너무 신난 상태로 코드를 짜서 그런지 코드가 많이 더럽다.

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

vector<int> visited;
vector<vector<int>> v;

int dfs(int node, int x) {
    visited[node] = 1;
    for (int i=0; i<v[node].size(); i++) {
        if (visited[v[node][i]])    continue;
        return dfs(v[node][i], x+1);
    }
    return x;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);  cout.tie(NULL);
    int n;
    int a[500005];
    int cnt[500005];
    int ans = 0;
    memset(cnt, 0, sizeof(cnt));
    cin >> n;
    
    v = vector<vector<int>>(n+1);
    visited = vector<int>(n+1, 0);
    
    for (int i=1; i<=n; i++) {
        cin >> a[i];
        if (a[i] < i && a[a[i]] == i) {	// 서로가 서로를 지목한 경우;
            continue;
        }
        v[i].push_back(a[i]);
        v[a[i]].push_back(i);
        cnt[a[i]]++;	// 연결된 간선 개수
        cnt[i]++;
    }
    
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    for (int i=1; i<=n; i++) {
        pq.push({cnt[i], i});
    }
    
    while (!pq.empty()) {
        int sz = pq.top().first;
        int node = pq.top().second;
        pq.pop();
        if (visited[node])  continue;
        if (sz>1)  break;
        
        ans++;
        visited[node] = 1;
        for (int i=0; i<v[node].size(); i++) {
            int nnode = v[node][i];
            if (visited[nnode]) continue;
            visited[nnode] = 1;
            for (int j=0; j<v[nnode].size(); j++) {
                if (visited[v[nnode][j]])   continue;
                cnt[v[nnode][j]]--;
                pq.push({cnt[v[nnode][j]], v[nnode][j]});
            }
        }
    }
    
    for (int i=0; i<n; i++) {
        if (visited[i]) continue;
        ans += dfs(i, 1) / 2;
    }
    
    cout << ans;
}

5. 여담

오랜만에 정말 마음에 드는 문제를 풀었다. 관찰 과정부터 풀이 구현까지 전부 즐겁게 해결한 문제.

태그 중에 분리 집합이 있는 것을 보아하니 분리 집합으로도 풀 수 있는 모양이다.

 

220829 문제 풀이 기록

2022. 8. 29. 23:38

P3 | 6132 - 전화선

풀이 시간: 1시간

시도 횟수: 2회

체감 난이도: P3

풀이 쓸 의향: 上

풀이

더보기

동일한 수의 연속하는 원소는 반드시 동시에 올리거나 내려야 한다는 점을 잘 파악하여 증명한 뒤, 각 값과 연속되는 구간을 저장한 뒤 그리디하게 가장 작은 값들의 구간부터 1씩 올리면서 최적값 찾기

여담: 다른 사람들은 죄다 DP로 푼 것 같은데 나 혼자만 그리디로 푼 것 같다. 문제 관찰 과정과 그 관찰을 토대로 그리디 알고리즘을 구현하는 과정이 즐거웠다.

 

 

 

 

P5 | 1131 - 숫자

풀이 시간: 1시간 10분

시도 횟수: 2회

체감 난이도: P5

풀이 쓸 의향: 下

풀이

더보기

반드시 겹치는 사이클이 존재하는데, 해당 사이클을 잘 찾아서 연산하기

여담: 문제 보자마자 아이디어 거의 10분만에 떠올려놓고 구현에서 죽쑨거 못찾고 1시간 삽질함; 죽고싶다...

'PS > 풀이 기록장' 카테고리의 다른 글

220831 문제 풀이 기록  (0) 2022.08.31
220830 문제 풀이 기록  (0) 2022.08.30
220828 문제 풀이 기록  (0) 2022.08.28
220827 문제 풀이 기록  (0) 2022.08.27
220826 문제 풀이 기록  (0) 2022.08.27

220828 문제 풀이 기록

2022. 8. 28. 23:11

P3 | 12016 - 라운드 로빈 스케줄러

풀이 시간: 약 50분

시도 횟수: 2회

체감 난이도: P3 하위권

풀이 쓸 의향: 下

풀이

더보기

없어지는 원소들을 잘 관리하면서 세그먼트 트리 활용하기. 크기가 x인 값을 처리할 때 현재 시간이 몇인지 잘 기록하고, 이미 실행이 끝난 프로세스 값을 1로 바꾸면 구간합 세그트리로 해결 가능하다.

여담: 4년 전에는 뭣도 모르고 시간 초과를 냈던 문제인데, 이제야 스스로 해결할 수 있게 되었다. 만세!

딱히 재미있는 관찰이 필요한 게 아니라 세그트리를 잘 활용하기만 하면 풀리는 문제여서 딱히 재미는 없었다.

'PS > 풀이 기록장' 카테고리의 다른 글

220830 문제 풀이 기록  (0) 2022.08.30
220829 문제 풀이 기록  (0) 2022.08.29
220827 문제 풀이 기록  (0) 2022.08.27
220826 문제 풀이 기록  (0) 2022.08.27
220825 문제 풀이 기록  (0) 2022.08.25

220827 문제 풀이 기록

2022. 8. 27. 23:47

P5 | 15808 - 주말 여행

풀이 시간: 30분

시도 횟수: 무려 7회

체감 난이도: P5 하위권

풀이 쓸 의향: 下

풀이

더보기

각 여행지들을 각각 시작점으로 잡고 최대 힙으로 최대 기대치가 되는 다익스트라 돌리기

여담: 정답이 0보다 작을 수 있음을 고려하지 않고 풀다가 혼쭐났음. 아니 영선아 여행 기대치가 음수면 대체 왜 여행을 가는거니??

 

 

P4 | 14927 - 전구 끄기

풀이 시간: X

시도 횟수: 1회

체감 난이도: X

풀이 쓸 의향: 下

풀이

더보기

각 칸은 두번 이상 누를 일 없음 + 맨 윗줄을 어떻게 누르느냐에 따라서 아래쪽을 어떻게 눌러야 하는지 확정적으로 알 수 있음을 이용하여 브루트 포싱

여담: https://www.acmicpc.net/problem/14939 이전에 풀었던 문제와 너무 동일해서 그냥 풀이 박아버렸음... 솔직히 골드 난이도는 진짜 말도 안된다고 생각하고, 사람마다 개인차가 있겠지만 P5 ~ P4 사이인듯.

 

'PS > 풀이 기록장' 카테고리의 다른 글

220829 문제 풀이 기록  (0) 2022.08.29
220828 문제 풀이 기록  (0) 2022.08.28
220826 문제 풀이 기록  (0) 2022.08.27
220825 문제 풀이 기록  (0) 2022.08.25
220824 문제 풀이 기록  (0) 2022.08.24

220826 문제 풀이 기록

2022. 8. 27. 01:59

P5 | 9463 - 순열 그래프

걸린 시간: 20분

체감 난이도: 어쩔수 없이 P5 주는 정도

시도 횟수: 1회

풀이 쓸 의향: 下

풀이:

더보기

장황한 순열 그래프 뭐시기는 낚시용이고 그냥 교차하는 선분의 개수 구하면 됨. 위쪽 노드를  왼쪽부터 순서대로 고르면 (b[a[i]], n) 구간의 합을 구하는 세그트리로 구하면 됨.

여담: 그냥 세그트리 쓰면 풀리는 세그트리용 날먹 문제. seg 구현할때 등호 넣으면 안되는 식에 등호넣어서 5분 날림.

 

 

 

P4 | 1124 - 바닥 장식

걸린 시간: 1시간 30분

체감 난이도: P4 상위권

시도 횟수: 6회

풀이 쓸 의향: 下

풀이:

더보기

(x1, y1)에서 (x2, y2)까지 개수를 어떻게든 열심히 예외처리하면서 크기가 1, 2, 3, 4, 5인 개수 각각 다 구하고 그리디하게 큰것부터 넣어주면서 개수 세기

여담: 내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어내가이겼어

문제 보자마자 풀기싫어서 몸비틀다가 풀이 시작하자마자 문제 잘못읽고 풀다가 때려치려고 하다가 다시 풀다가 틀려서 예외처리하다가 정신이 나가버릴뻔함

저번에 풀었던 리그 (https://www.acmicpc.net/problem/3031)보다 예외 처리랑 구현 더 빡센 문제는 이게 처음인듯

 

풀이 메모

더보기

으악
으악 이게 뭐야
아니 이걸 풀라고? 아니 으악 살려줘 으악

ㅡ ㅣ ㅡ ㅣ ㅡ ㅣ
ㅣ ㅡ ㅣ ㅡ ㅣ ㅡ
ㅡ ㅣ ㅡ ㅣ ㅡ ㅣ
ㅣ ㅡ ㅣ ㅡ ㅣ ㅡ

높이가 5면 당연히 위아래 5인거 넣는게 최적임. 그니까 틀에 딱 맞춰서 넣는게 최적이다.
높이가 6이면? ㅡ 로 돼있는거는 그냥 하나 추가지만, ㅣ로 돼있는거는 5개나 추가되니까, 그리고 어차피 나열되니까
사실 높이가 뭐든지간에 위쪽을 틀에 딱 맞추는게 그냥 최적임
뭐 높이를 맞추든 너비를 맞추든 그게 그거같지만 아무튼 가장 윗변을 맞춰서 가자.
그럼 이제 좌우로 움직이면서 .. 어라 ㅅㅂ 잠깐만?
아냐 이게 맞아

이제 좌우만 따지면 되는데
근데 똑같은 논리로 그럼 좌우도 면에 딱 붙이는게 최적이어야 되는거 아님??
그냥 왼쪽 위에 맞춰서 계산하면 되는거 아님???

아니 문제 잘못읽었네 ㅅㅂㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
어쩐지 쉬워보이더라
그래도 접근은 비슷하게 하면 될것 같은데...
아니네


일단 문제 파트가 두갠데
1. (x1, y1), (x2, y2)에 있을 때 크기 1인거부터 5인거까지의 개수 구하기
2. 크기 1인거부터 5인거까지 개수가 있을 때, 크기 5 최소 개수만 써서 그거 만들기


근데 2.는 쉬운게
4를 만드려면 어차피 1이 나오게 되어 있음 --> 4 최대한 만들자
3 만들면 1 1 이나 2로 사용 가능한데, 1 만드는게 더 쉬우니까 3 개수에서는 2 최대한 넣고 넣은 후에는 다 1 넣으면 됨
그냥 그리디로 짜면 된다

1번이 문제야 1번이 ㅅㅂ 개귀찮아
이게 가운데 있는 꽉 찬 애들은 그냥 하면 되는데
끝부분 잘라먹기를 해야되는게 참...
개하기싫다
푼사람도 얼마 없겠지
22명이면 생각보다 많네
플4는 풀이를 도전하는 용기에서 나오는 난이도인건가
ㅅㅂ...

2 2 8 8
(2, 2) ~ (5, 2)
(5, 2) ~ (8, 2)


아 괜찮은 방법 없나?

어차피 뭐 좌표 크더라도 왼쪽 위를 왼쪽 위쪽으로 옮기면 무조건 왼쪽 위 좌표는 (10, 10)보다 왼쪽 위로 압축이 가능한데
전체에서 (0, 0) ~ (10, 10)는 그냥 다 저장 해 둔 상태에서, 범위 따라 구현하자

아익

상하좌우 그냥 다 해버리자
안해시발

후.... 그래 그래도 해야지 ㅅㅂ
왼쪽에 겹친 ㅡ 부분의 개수, 오른쪽에 겹친 ㅡ 부분의 개수, 위쪽에 

(8, 5) ~ (20, 16)에서,
(8, 5) ~ (10, 16)에 있는 ㅡ의 개수 : 6, 크기 : 2
(8, 16) ~ (20, 16)에 있는 ㅣ의 개수 : 5, 크기 : 1
나머진 모두 안에 있으니 그냥 하면 됨

ㅇ?ㅇ?ㅁㄴㅇ?ㅁ?ㅃ?!@?# ㅃ!?ㅇㄹㄴ ?ㅁㄴㅇ?ㄹ ㄴㅁㅇ? #? ?

4 0 10 2

 

 

 

 

P3 | 21725 - 더치페이

걸린 시간: 1시간 15분

체감 난이도: P3 중/하위권

시도 횟수: 9회

풀이 쓸 의향: 中

풀이:

더보기

disjoint set으로 합쳐 가되, 작은 집합과 큰 집합을 합칠 때는 작은 집합 값을 정리해주며 진행. 한 그래프 안에서의 총 지출 금액과 각 사람이 지출한 금액을 저장하고, 마지막에 쭉 돌려주면 각 사람이 내야 하는 / 받아야 하는 금액이 전부 나오고, 한명 총무로 삼아서 돈 송금하면 된다.

여담: 돈 0원 송금하면 안된다는 조건 때문에 한번 틀렸고, 다른 별 이상한 실수해서 틀렸던건데 풀이 증명 다시하고 반례 이것저것 넣고 assert 조지고 하느라 시도 횟수가 늘어났다.

아니 문제 알고리즘 바로 떠올리고 잘 풀어놓고 왜 구현에서 이상한 실수 하는지 모르겠는데 그냥 지금 졸려서 그렇다고 생각하자...

 

풀이 메모

더보기

disjoint set

각 사람이 다른 사람들에게 내야 하는 돈의 양을 저장해 두자
라고는 해도?
이거 어떻게 구현하지
뭔가 정공법으로 자료구조 짜야될거 같은 듯한 그런 느낌

아 잠깐만
1->2 2->3 같이 송금하는게 가능하잖아?
지출 금액을 생각하면

(지출 금액 - 빚진 금액(자기에게 빚진것도 포함))을 저장하자

가령 예제의 경우,
1: 20 / 2: -31 / 3: 11

2가 1에게 20, 2가 3에게 11 주면 그냥 되잖아

근데 해당 그래프에 있는 모든 사람들에게 적용하는거?
합쳐질때 넣으면 됨
그니까 한 그래프의 루트에 (또는 그냥 구조체 만들어서) 박은 다음에
합쳐지기 전에 나눠주자


그럼 그냥 나눠주는게 아니라 
sz 자체가 작은 쪽이 큰 쪽에 융화되면 될듯?

그니까 노드 개수가 적으면 

노드에 각자가 지출한 금액을 넣어두고, 각 그래프에 대해 각자가 지출한 금액의 값의 합을 저장하자
나중에 계산할때는 각 그래프에 대해 (그래프 총 지출금 / 그래프 크기)만큼 내야 하는 돈을 추가해 준다.

크기가 작은 쪽이 큰 쪽과 융합될 때, (큰 지출금 / 큰 크기)
?
융합되면 그냥 똑같나?
그건 아니네
어차피 나중에 total 값을 저장할거니까
작은 그래프 청산 하고나서 큰 그래프에 넣어주자

가령
   40            24
4 8 12 16    10 14
라고 한다면
24 / 10 14 그래프를 먼저 조져서 total값에 각각 10-12, 14-12 값을 더해주고
노드값을 40/4=10으로 초기화해준 다음에 total값은 40/4*2만큼 늘려준다.

disjoint set을 구현하면서 size를 넣어주고,
해당 disjoint set에 들어 있는 노드들을 저장해 주고
ㅇㅋ
ㄱㄱ'

잠깐!

노드값들은 그냥 tot값에만 저장하고
sum 만 더해주면 나중에 문제 없다
그니까 tot 이 10, 14일때, 24/2를 빼고 40/4를 더해주자.

-20 -5 10 15

ㅇㅎ..

그냥 1번이 총무 하자 ㅋㅋ

5 7
1 2 3
1 4 5
2 2 2
2 3 2
2 4 6
2 5 6
1 1 5

220825 문제 풀이 기록

2022. 8. 25. 23:16

G5 | 14699 - 관악산 등반

걸린 시간: 약 15분 (부정확)

체감 난이도: G5 ~ G4 사이 그 어딘가 애매한 지점

시도 횟수: 1회

풀이 쓸 의향: 下

풀이:

더보기

높이 있는 노드부터 차례대로 내려오면서 최대값 저장하기.

여담: 친구가 암만봐도 골드 5 아닌것같다고 해서 풀어본 문제.

솔직히 아이디어 자체는 G5가 맞는데 그래프기도 하고 이런저런 구현방법 잘 모르면 시간 끌릴수도 있겠다 싶어서 G4로 난이도 기여함.

 

 

P5 | 2463 - 비용

걸린 시간: 45분

체감 난이도: P4 하위권

시도 횟수: 2회

풀이 쓸 의향: 中

풀이:

더보기

비용 큰 간선부터 차례대로 간선 연결하면서, disjoint set으로 간선이 연결하는 그래프의 크기 고려하면서 정답값 더해주기.

여담: disjoint set 구현할 때 두 root값(그래프 크기값)을 곱하는 부분이 있었는데, root값을 int로 둬서 한번 틀림.

솔직히 처음 봤을때 바로 MST(Maximum)이 떠올랐는데, 실상 풀이는 MST를 안쓰는게 더 편해서 오히려 생각이 더 꼬였던 것 같다.

(풀이 메모)

더보기

가중치가 가장 작은 / 큰 간선은 몇 번 제거될까

작은 간선들을 보면?
가령 가중치가 2인 간선은 그냥 뭘 해도 다 없어지네?
!
MST
MST...가 맞나
Maximum?
Maximum spanning tree를 구성하자.

그럼 예제 그래프에서 남는 간선들이?
15 10 6 5 4가 된다
제거되는건 2, 3 <-- 얘들은 모든 두 정점 (u, v)에 대해 그냥 계속 없어지니까, N(N-1)/2번 없어진다
이제 작은것부터 보자
4도 뭘 해도 끊어진다
5는? (4 끊을때 5번 노드가 끊기므로) 5번 노드가 들어간 거 빼고는 다 끊어진다
6은? (5 끊을때 4번 노드가 끊기므로) 4번 노드가 들어간 거 빼고는 다 끊어진다
10은? (6 끊을때 그래프가 1-2, 3-6으로 나뉘므로) 


그래프가 나뉘는데, 각 그래프의 크기에 대해
어떤 한 그래프에서 다른 그래프로 연결하는 개수만큼..? 쫌 복잡하네요,,, 으엑

(1, 2) : 10 이하 다 끊김
(1, 6) : 6 이하 다 끊김
(1, 3) : 6 이하 다 끊김
근데 이렇게하면... N^2이잖아...

모든 그래프에서, 각 그래프 크기를 x라 하면,
sum(x(x-1)/2);
이게 깔끔하네
4:15
5:10
6:6
10:2
15:1

9*15 + 50 + 36 + 20 + 15



근데 구현을 어케함 이걸
uf 쓰기 싫은데
아니 uf 써도 시간 안에 되나
끊는거보단 잇는게 쉬우니깐...
큰거부터 이어볼까

!!

큰거부터 이어서 조지자
연결됐을 때, (x + = sz[s]*sz[e]), ans += v[node] * x;

ㄱㄱㄱㄱㄱㄱ
근데.. 그럼 사실 MST 필요없는거 아닌가
으익..!!!!
이미 연결되어 있었다면 x 증가 안시키고, 연결 안되어있었을 때만 증가시키게 하면 될듯
ㄱㄱ

220824 문제 풀이 기록

2022. 8. 24. 22:36

P4 | 1280 - 나무 심기

걸린 시간: 약 40분 (부정확)

체감 난이도: P5 상위권

시도 횟수: 3회

풀이 쓸 의향: 下

풀이

더보기

세그트리에 값 하나가 아니라 두개를 넣거나 두개의 세그트리를 따로 만들어서 값을 구하면 되는 문제.

여담: 

나머지 연산 실수때문에 한 번, 값 범위가 0부터 시작인거 못봐서 한 번 틀렸다.

 

 

P5 | 14572 - 스터디 그룹

걸린 시간: 약 30분

체감 난이도: P5 하위권

시도 횟수: 1회

풀이 쓸 의향: 下

풀이

더보기

실력 차이가 D 이하인 가장 큰 구간을 투 포인터로 구하고 나서 그 안에 사람들 죄다 돌려보며 구하기

여담: vector<pair<int, vector<int>>>라는 괴상한 자료구조를 만들어서 풀었다.

실력 차이가 D 이하인 모든 구간에서 최대한 많은 사람을 넣도록 투포인터로 풀린다는 아이디어가 쉬운 사람한테는 너무 쉽고, 어려운 사람한테는 너무 어렵게 보일만 한듯.

 

 

P3 | 10542 - 마피아 게임

걸린 시간: 1시간 10분

체감 난이도: P3

시도 횟수: 8회

풀이 쓸 의향: 上

풀이

더보기

문제 상황을 그래프로 추상화한 뒤에 관찰을 통해 terminal node를 고르는 것이 최적이라고 증명한 뒤 나머지 남은 cycle은 dfs 돌리면서 size/2만큼씩 더해준다.

여담: 정말 재밌게 푼 문제.

중간에 많이 해메서 좀 코드가 많이 더럽다. 남은 cycle 처리를 이상하게 해서 자꾸 틀리다 결국 발견해서 풀었다.

 

(풀이 메모)

더보기

서로 지목하지 않은 사람의 최대 수
그래프로 생각하면

어떤 그룹이 있을 때, 해당 그룹끼리는 서로 화살표가 연결되어있지 않은 최대 크기의 그룹?

1->3
2->3
3->4
4->5
5->6
6->4
7->4

?
노드 N개, 간선 N개인 그래프
사실 유향 그래프일 필요가 없는게 연결되어 있으면 절대 서로가 마피아가 아님.
홀짝놀이

노드 N개, 간선 N개인 무향 그래프에서 서로 이웃하지 않은 노드들의 최대 갯수

간선 N개인게 많이 중요할까
읆...

dfs dp로 되나

cycle 하나 떼면 트리인데...

dp[x][0] : x번 노드가 마피아가 아닐 때, dp[x][1] : x번 노드가 마피아일때 
쩝,,


연결된 개수가 작은걸 제일 먼저 고르는게 무조건 낫나?
그니까 어떤 노드를 고르면 연결된 다른 노드를 절대 고를 수 없는데, 어떤 노드를 고르지 않으면 다른 노드를 고를 수 있는 가능성이 생긴다
가령 1-3 끊으면 1, 3 disable, 2:0, 4:3
2


간선 N개니까 시간 안에 됨
제일 작은거부터 고르되, 제일 작은게 누구인지 계속 봐줘야됨



이거 뭔가 증명이 안되는데...
!
terminal을 고르는 것이 무조건 best이다
그럼 계속 terminal을 찾아서 제거하자

 

 

+ Recent posts