[문제]

그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 더 이상 방문할 수 있는 점이 없는 경우 종료한다. 정점 번호는 1번부터 N번까지이다.

 

[입력]

첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다.

 

[출력]

첫째 줄에 DFS를 수행한 결과를, 그 다음 줄에는 BFS를 수행한 결과를 출력한다. V부터 방문된 점을 순서대로 출력하면 된다.

 

[예제]


>문제 풀이

 DFS와 BFS에 대한 이해가 있었다면 풀 수 있는 가장 기본적인 문제인 것 같다.

그러나, 나는 이해가 없었기에,, 개념부터 공부하고 이 문제를 풀었다.

 

>전체 코드

 

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
	static int N, M, V;
	static int visit[], mat[][];
	
	public static void main(String [] args) {
		int p1, p2;
		
		Scanner scan= new Scanner(System.in);
		
		N= scan.nextInt();
		M= scan.nextInt();
		V= scan.nextInt();
		
		visit= new int[N+1];
		mat= new int[N+1][N+1];
		for(int i=0; i<M; i++) {
			p1= scan.nextInt();
			p2= scan.nextInt();
			mat[p1][p2]=mat[p2][p1]=1;
		}
		
		dfs(V);
		System.out.println();
		Arrays.fill(visit, 0); //초기화
		bfs(V);
		
	}
	
	public static void dfs(int start) {
		visit[start]=1;
		System.out.print(start+" ");
		for(int i=1; i<=N; i++) {
			if(mat[start][i]==1 && visit[i]!=1) {
				dfs(i);
			}
		}
	}//dfs
	
	public static void bfs(int start) {
		int temp;
		Queue<Integer> queue= new LinkedList<Integer>();
		queue.offer(start);
		visit[start]=1;
		System.out.print(start+" ");
		
		while(!queue.isEmpty()) {
			temp= queue.poll();
			for(int i=1; i<=N; i++) {
				if(mat[temp][i]==1&&visit[i]!=1) {
					queue.offer(i);
					visit[i]= 1;
					System.out.print(i+" ");
				}
			}
		}
		
	}//bfs
}

www.acmicpc.net/problem/1260

 

1260번: DFS와 BFS

첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사

www.acmicpc.net

 

[문제]

우리는 스마트폰을 사용하면서 여러 가지 앱(App)을 실행하게 된다. 대개의 경우 화면에 보이는 ‘실행 중’인 앱은 하나뿐이지만 보이지 않는 상태로 많은 앱이 '활성화'되어 있다. 앱들이 활성화 되어 있다는 것은 화면에 보이지 않더라도 메인 메모리에 직전의 상태가 기록되어 있는 것을 말한다. 현재 실행 중이 아니더라도 이렇게 메모리에 남겨두는 이유는 사용자가 이전에 실행하던 앱을 다시 불러올 때에 직전의 상태를 메인 메모리로부터 읽어 들여 실행 준비를 빠르게 마치기 위해서이다.

하지만 스마트폰의 메모리는 제한적이기 때문에 한번이라도 실행했던 모든 앱을 활성화된 채로 메인 메모리에 남겨두다 보면 메모리 부족 상태가 오기 쉽다. 새로운 앱을 실행시키기 위해 필요한 메모리가 부족해지면 스마트폰의 운영체제는 활성화 되어 있는 앱들 중 몇 개를 선택하여 메모리로부터 삭제하는 수밖에 없다. 이러한 과정을 앱의 ‘비활성화’라고 한다.

메모리 부족 상황에서 활성화 되어 있는 앱들을 무작위로 필요한 메모리만큼 비활성화 하는 것은 좋은 방법이 아니다. 비활성화된 앱들을 재실행할 경우 그만큼 시간이 더 필요하기 때문이다. 여러분은 이러한 앱의 비활성화 문제를 스마트하게 해결하기 위한 프로그램을 작성해야 한다

현재 N개의 앱, A1, ..., AN이 활성화 되어 있다고 가정하자. 이들 앱 Ai는 각각 mi 바이트만큼의 메모리를 사용하고 있다. 또한, 앱 Ai를 비활성화한 후에 다시 실행하고자 할 경우, 추가적으로 들어가는 비용(시간 등)을 수치화 한 것을 ci 라고 하자. 이러한 상황에서 사용자가 새로운 앱 B를 실행하고자 하여, 추가로 M 바이트의 메모리가 필요하다고 하자. 즉, 현재 활성화 되어 있는 앱 A1, ..., AN 중에서 몇 개를 비활성화 하여 M 바이트 이상의 메모리를 추가로 확보해야 하는 것이다. 여러분은 그 중에서 비활성화 했을 경우의 비용 ci의 합을 최소화하여 필요한 메모리 M 바이트를 확보하는 방법을 찾아야 한다.

 

[입력]

입력은 3줄로 이루어져 있다. 첫 줄에는 정수 N과 M이 공백문자로 구분되어 주어지며, 둘째 줄과 셋째 줄에는 각각 N개의 정수가 공백문자로 구분되어 주어진다. 둘째 줄의 N개의 정수는 현재 활성화 되어 있는 앱 A1, ..., AN이 사용 중인 메모리의 바이트 수인 m1, ..., mN을 의미하며, 셋째 줄의 정수는 각 앱을 비활성화 했을 경우의 비용 c1, ..., cN을 의미한다

단, 1 ≤ N ≤ 100, 1 ≤ M ≤ 10,000,000이며, 1 ≤ m1, ..., mN ≤ 10,000,000을 만족한다. 또한, 0 ≤ c1, ..., cN ≤ 100이고, M ≤ m1 + m2 + ... + mN이다.

 

[출력]

필요한 메모리 M 바이트를 확보하기 위한 앱 비활성화의 최소의 비용을 계산하여 한 줄에 출력해야 한다. 

 

[예제]

 


>문제 이해

어우 문제가 뭐가 이렇게 긴지...ㅎㅎ

 

배열의 사이즈 N과 필요한 메모리의 양 M이 먼저 주어집니다.

그리고 두번째 줄에 memory[N]과 세번째 줄에 cost[N]이 차례로 주어집니다.

이제 최소 비용으로(cost) M이상의 메모리를 만드는 방법을 찾아야 합니다.

이 때 cost를 출력하면 되는 문제

 

>문제 풀이

 1차원 배열 dp[]를 선언하는데, []괄호 안에는 비용이 들어갑니다.

입력 조건에 따라 10000이 최대이긴 하지만, 저는 sum을 구해서 dp= new int[sum]으로 선언했습니다.

 

예제로 dp가 어떻게 되는지 알아보겠습니다.

cost의 합(sum)= 15 -> dp[15]

	//dp
	dp= new int[sum+1];
	for(int i=0; i<N; i++) {
		for(int j=sum; j>=cost[i]; j--) {
			dp[j]=Math.max(dp[j], dp[j-cost[i]]+memory[i]);
		}
	}

dp[j]는 j만큼의 비용을 가지고 있었을 때, 가질 수 있는 메모리의 최대값을 담은 배열값입니다.

점화식: dp[j]=Math.max(dp[j], dp[j-cost[i]]+memory[i]);

 

다음은 for문의 반복에 따라 dp[]값의 변화입니다.

 

*두번째 for문에서 sum~cost[i]로 j-- 반복을 하는 이유는,

j-cost[i]<j로 dp[j]값에 dp[j-cost[i]]가 영향을 미치기 때문에 뒤의 값부터 갱신을 시작해야합니다.

 

 

이렇게 dp배열을 전부 채우고 나면,

dp[i]>=M가 되는 i를 찾아 출력해주면 됩니다.

 

>전체 코드

 

import java.io.BufferedReader;
import java.util.StringTokenizer;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
	
	public static void main(String [] args) throws IOException {
		int N, M, sum=0;
		int memory[], cost[], dp[];
		
		//입력받기
		BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st= new StringTokenizer(br.readLine());
		
		N= Integer.parseInt(st.nextToken());
		M= Integer.parseInt(st.nextToken());
		memory= new int[N];
		cost= new int[N];
		
		st= new StringTokenizer(br.readLine());
		for(int i=0; i<N; i++) {
			memory[i]= Integer.parseInt(st.nextToken());
		}
		
		st= new StringTokenizer(br.readLine());
		for(int i=0; i<N; i++) {
			cost[i]= Integer.parseInt(st.nextToken());
			sum+=cost[i];
		}
		
		//dp
		dp= new int[sum+1];
		for(int i=0; i<N; i++) {
			for(int j=sum; j>=cost[i]; j--) {
				dp[j]=Math.max(dp[j], dp[j-cost[i]]+memory[i]);
			}
		}
		
		//출력
		for(int i=0; i<=sum; i++) {
			if(dp[i]>=M) {
				System.out.println(i);
				break;
			}
		}
		br.close();
	}
}

www.acmicpc.net/problem/7579

 

7579번: 앱

입력은 3줄로 이루어져 있다. 첫 줄에는 정수 N과 M이 공백문자로 구분되어 주어지며, 둘째 줄과 셋째 줄에는 각각 N개의 정수가 공백문자로 구분되어 주어진다. 둘째 줄의 N개의 정수는 현재 활

www.acmicpc.net

 

+ Recent posts