음.. 처음에 문제를 보고 난해했다.


그런데 조금 검색해보면서 확인해보니 위상정렬이나 DP로 풀 수 있다는걸 알고,

생각을 좀 해봤다.


일단 그래프인건 확실하고, 중등부여서 데이터도 적고 하니 DP로 풀자 생각했다.

DAG여서 1에서 끊어줘야되고, 시간초과가 나니까 Memorization도 해줘야 됐다.

그리고 순서를 표시하기 위해 disjoint-set도 했다. (트리구조로 parent를 찾아감)

import java.io.*;
import java.util.*;
/**
* BOJ 2611 자동차경주
* https://gist.github.com/KSH-code/6ef723e29a1cffa75f4a429984047cd7
*/
class Edge{
public int V,W;
public Edge(int v, int w){
V = v;
W = w;
}
}
public class Main{
private static int V[];
private static int MAX[];
private static ArrayList<Edge> E[];
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int M = Integer.parseInt(br.readLine());
V = new int[N+1];
E = new ArrayList[N+1];
MAX = new int[N+1];
for(int i = 1; i<=N; i++){
E[i] = new ArrayList<>();
}
for(int i = 0; i<M; i++){
String str1[] = br.readLine().split(" ");
int s = Integer.parseInt(str1[0]);
int e = Integer.parseInt(str1[1]);
int w = Integer.parseInt(str1[2]);
E[s].add(new Edge(e, w));
}
System.out.println(checkWeight(1, 0));
printTree(1);
}
public static int checkWeight(int v, int w) {
LinkedList<Edge> e = new LinkedList<>();
int max = 0;
int tempWeight = 0;
if(MAX[v] > 0){
max = MAX[v];
}else if(E[v].size() > 0){
for(int i = 0; i<E[v].size(); i++){
e.add(E[v].get(i));
}
if(v == 1) E[v].clear();
while(!e.isEmpty()){
Edge temp = e.remove();
tempWeight = checkWeight(temp.V, temp.W);
if(tempWeight > max){
V[v] = temp.V;
max = tempWeight;
}
}
MAX[v] = max;
}
return w + max;
}
private static void printTree(int i){
if(V[i] == 1){
System.out.print(i + " ");
System.out.print(1);
}else{
System.out.print(i + " ");
printTree(V[i]);
}
}
}
view raw Main.java hosted with ❤ by GitHub


disjoint-set 을 처음 공부했다.


서로소에 대해서 기억이 가물가물해 찾아봤는데, 서로 다른 숫자의 집합.



이 문제는 disjoint-set에 대해 기초만 알면 되는데, find, link만 알면 된다.



import java.io.*;
import java.util.*;
/**
* BOJ 1717 집합의 표현
*/
public class Main{
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String str1[] = br.readLine().split(" ");
int n = Integer.parseInt(str1[0]), m = Integer.parseInt(str1[1]);
int disjoint[] = new int[n+1];
for(int i = 0; i<=n; i++){
disjoint[i] = i;
}
for(int i = 0; i<m; i++){
String str2[] = br.readLine().split(" ");
int a = Integer.parseInt(str2[0]), b = Integer.parseInt(str2[1]), c = Integer.parseInt(str2[2]);
if(a == 0){
// c 의 부모를 b의 부모로 한다.
link(disjoint, b, c);
}else{
// c의 부모와 b의 부모가 맞다면
if(find(disjoint, b) == find(disjoint, c))
bw.write("YES");
else
bw.write("NO");
bw.write("\n");
}
}
bw.flush();
}
/**
* 트리 구조이기 때문에 루트를 변겅하면 그 밑에것들은 알아서 따라오게 된다.
*/
private static void link(int dis[], int x, int y){
dis[find(dis, y)] = find(dis, x);
}
/**
* 트리 구조에서 루트를 찾기위해 재귀함수를 이용한다.
*/
private static int find(int dis[], int x){
if(dis[x] == x) return x;
else return dis[x] = find(dis, dis[x]);
}
}

+ Recent posts