https://www.acmicpc.net/problem/1260
위 문제를 풀어보도록 하겠다.
-- | 입력 | 출력 |
---|---|---|
예제 입력 1 | 4 5 1 1 2 1 3 1 4 2 4 3 4 | 1 2 4 3 1 2 3 4 |
위는 1번 테스트 케이스의 그래프 이다.
-- | 입력 | 출력 |
---|---|---|
예제 입력 2 | 5 5 3 5 4 5 2 1 2 3 4 3 1 | 3 1 2 5 4 3 1 4 2 5 |
위는 2번 테스트 케이스의 그래프 이다.
예제 출력 3은 생략.
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int nodeCount = sc.nextInt();
int lineCount = sc.nextInt();
int startNode = sc.nextInt();
Node[] nodes = new Node[nodeCount+1];
for(int i=0; i<nodeCount+1; i++)
nodes[i] = new Node(i);
for(int i=0; i<lineCount; i++){
int s = sc.nextInt();
int e = sc.nextInt();
nodes[s].addSide(nodes[e]);
nodes[e].addSide(nodes[s]);
}
for(Node n : nodes)
n.neighbours.sort(new Com());
DFS(nodes[startNode]);
System.out.println();
reset(nodes);
BFS(nodes[startNode]);
}
static void reset(Node[] nodes){
for(Node v : nodes)
v.visited=false;
}
static void DFS(Node node){
node.visited=true;
System.out.printf("%d",node.info);
List<Node> list = node.getSide();
for(Node n : list){
if(!n.visited) {
System.out.print(" ");
DFS(n);
}
}
}
static Queue<Node> queue = new LinkedList<>();
static void BFS(Node node){
node.visited = true;
queue.add(node);
System.out.print(node.info);
while(!queue.isEmpty()){
Node v = queue.remove();
List<Node> neigh = v.neighbours;
for(Node w : neigh){
if(!w.visited){
System.out.print(" "+w.info);
w.visited = true;
queue.add(w);
}
}
}
}
}
class Com implements Comparator<Node>{
@Override
public int compare(Node o1, Node o2) {
return Integer.compare(o1.info, o2.info);
}
}
class Node {
int info;
boolean visited;
List<Node> neighbours; //인접 목록
Node(int info){ //생성자
this.info = info;
this.visited = false;
this.neighbours = new ArrayList<>();
}
public void addSide(Node n) { //인접 목록 채우기
this.neighbours.add(n);
}
public List<Node> getSide(){ //인접 목록 반환
return neighbours;
}
public void setSide(List<Node> n) { // 인접 목록 세팅
this.neighbours = n;
}
@Override
public String toString() { //출력 오버라이딩
return "" + info;
}
}
만약, DFS를 재귀가 아닌 Stack으로 구현하고 싶다면, 아래의 코드를 참고하면 된다.
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int nC = sc.nextInt();
int lC = sc.nextInt();
int sNN = sc.nextInt();
// nC = nodeCount
// lC = lineCount
// sNN = startNodeNumber
Node[] nodes = new Node[nC];
for(int i=0; i<nC; i++){
nodes[i] = new Node(i);
}
for(int i=0; i<lC; i++){
int sN = sc.nextInt();
int eN = sc.nextInt();
// sN = startNode
// eN = endNode
nodes[sN].addNode(nodes[eN]);
nodes[eN].addNode(nodes[sN]);
}
DFS(nodes, sNN);
}
static void DFS(Node[] nodes, int sNN){
Stack<Node> stack = new Stack<>();
Node n = nodes[sNN];
n.setVisit(true);
System.out.print(n.getValue());
stack.push(n);
while(!stack.empty()){
Node tN = stack.peek();
boolean test = false;
// tN = topNode
for(Node sN : tN.getNodeList()){
// sN = sideNode (인접 노드)
if(!sN.getVisit()){
sN.setVisit(true);
System.out.print(" " + sN.getValue());
stack.push(sN);
test = true;
break;
}
}
if(!test)
stack.pop();
}
}
}
class Node {
private final int value;
private boolean visit;
private List<Node> nodeList;
public Node(int value) {
visit = false;
nodeList = new ArrayList<>();
this.value = value;
}
public void addNode(Node node) {
nodeList.add(node);
}
public int getValue() {
return value;
}
public boolean getVisit() {
return visit;
}
public void setVisit(boolean visit) {
this.visit = visit;
}
public List<Node> getNodeList() {
return nodeList;
}
@Override
public String toString() {
return "" + value;
}
}
node가 여러개인 경우, 숫자가 작은 node를 선택해야 하는데, 이것을 어떻게 할지 고민하다가 Comparator를 구현하고 sort메서드에 Comparator 인스턴스를 넘겨주었다.
따라서 node 목록이 크기순으로 정렬된다.
이렇게 하면, node를 뽑을때 저장된 순서로 뽑히므로 작은 node부터 뽑을 수 있다.
인접 행렬을 사용하면 편하지만, 그래프의 크기가 커지면 인접 목록보다 성능이 급격하게 떨어지므로 목록을 사용해서 구현했다.
고생하셨습니당