1. 문제

2. 접근방법

ㄷㄷㄷㅈ 제목이 신난다.

 

정점 4개로 만들 수 있는 모양 ㄷ과 ㅈ에 관한 문제

정점의 갯수가 30만개 까지 나오니 모든 경우의수를 구해서 풀면 당연히 안된다.

그러니 다른 방법을 찾아보자

 

먼저 ㄷ이랑 ㅈ의 특징을 보면

ㄷ 친구는 선 2개짜리 2개 1개 짜리 2개 씩 있다.

 

 

 

ㅈ 친구는 선 3개 정점 하나랑 선 1개짜리 정점 3개가 있다.

 

 

 

 

 

ㅈ부터 살펴보면 한 정점을 중심으로 3개의 선을 선택 하면 되는데

D을 중심으로 보면

요렇게 4가지 경우가 나올 수 있다.

즉 D에 연결된 4개 중에서 3개를 고르는 NC3 의 갯수를 구하면 된다.

 

그 다음 ㄷ을 보면

연결된 정점의 수가 1 2 2 1 이니

 

D를 기준으로 봤을때

부모와 나를 선택하고

부모에서 한개 나에서 한개 씩 고르면 된다.

즉 (부모한테 연결된것 -1) * (나한테 연결된것 -1)를 하면 한 정점에서의 ㄷ 갯수를 구할 수 있다.

 

3. 풀이

1. 정점의 갯수를 입력받고 각 부모를 저장할 list(parents)와 각 정점에 연결된 정점의 수를 저장할 list(lineNum) 생성

2. 입력 받은 간선배열에서 양쪽 정점의 lineNum에 +1

3. 간선배열은 부모 자식 짝 맞추기 위해 인접리스트에 저장 해 두었다가

4. bfs를 돌며 부모 자식 짝 맞추기

5. 이제 각 정점에 대해 ㅈ의 갯수는 N C 3으로 ㄷ의 갯수는 (부모의 갯수 - 1) * (자식의 갯수 -1) 로 구해 총 ㄷ의 갯수와 ㅈ의 갯수 세기

6. 각 상황에 맞는 D , G , DUDUDUNGA 출력

 

 

4. 자바 코드

package Gold;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class P19535ㄷㄷㄷㅈ {
	
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		int N = Integer.parseInt(br.readLine());
		int parents [] = new int [N+1];
		int lineNum [] = new int [N+1];
		ArrayList<Integer>[] list = new ArrayList[N+1];
		for(int i = 0 ; i < N+1 ; i++)
			list[i] = new ArrayList<Integer>(); //부모 자식 짝맞추기 용
		
		for(int i = 0 ; i < N+1 ; i++)parents[i] = i;
		
		for(int i = 0 ; i < N-1 ; i++) {
			st= new StringTokenizer(br.readLine());
			int start = Integer.parseInt(st.nextToken());
			int end = Integer.parseInt(st.nextToken());
			list[start].add(end);
			list[end].add(start);
			parents[end] = start;
			lineNum[start]++;
			lineNum[end]++;
		}
		
		Queue<Integer> que = new LinkedList<Integer>();
		que.offer(1);
		while(!que.isEmpty()) {
			int now = que.poll();
			for(int i = 0 ; i < list[now].size(); i++) {
				int target = list[now].get(i);
				if(parents[now] == target)
					continue;
				parents[target] = now;
				que.offer(target);
			}
		}
		
		
		
		long E = 0; //ㄷ
		long W = 0; //ㅈ
		for(int i = 1 ; i < N+1 ; i++) {
			long myNum = lineNum[i];
			long parentNum = lineNum[parents[i]]; 
			if(myNum >= 3 ) W += myNum*(myNum-1)*(myNum-2)/1/2/3;
			if(parents[i] != i)E += (myNum-1) * (parentNum -1);
		}
		
		String result = "";
		if(E > W*3)result = "D";
		else if(E == W*3)result = "DUDUDUNGA";
		else if(E < W*3)result = "G";
		System.out.println(E+ " " + W);
		System.out.println(result);
	}

}

5. 마치며

처음에 테케는 맞는데 틀렸습니다가 떠서 왜 그런지 보니

그래프에서 숫자가 작을 수록 rank가 당연히 낮겠지 생각하고 부모자식을 이어줬던게 문제였다.

다시 인접리스트로 받아서 제대로 짝지어주니 바로 통과 되었다.

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

[백준] 17472 다리만들기2  (0) 2020.09.04
[백준] 2933미네랄  (0) 2020.09.03
[백준] 18513 샘터  (0) 2020.08.31
[백준] 17471 게리멘더링  (0) 2020.08.28
[백준] 2206 벽 부수고 이동하기  (0) 2020.08.26

+ Recent posts