금요일이다. 햄보카다.
✨내용에 관여하지 않음
메서드 명 | 선언부와 설명 |
---|---|
File() | public File(String pathname) : pathname에 해당하는 파일을 생성한다. 경로 없이 파일을 생성하면 애플리케이션을 시작한 경로가 됨. |
public File(File parent, String child) : parent 경로 아래 child를 생성 | |
public File(URI uri) : file로 시작하는 URI 객체를 이용해 파일을 생성한다. | |
createNewFile() | public boolean createNewFile() throws IOException : 새로운 물리적인 파일을 생성. |
mkdir() | public boolean mkdir() : 새로운 디렉토리 생성 |
mkdirs() | public boolean mkdirs() : 경로상에 없는 모든 디렉토리를 생성 |
delete() | public boolean delete() : 파일 또는 디렉토리 삭제 |
객체를 파일 등에 저장하거나 네트워크로 전송하기 위해 연속적인 데이터로 변환하는 것
말이 어렵지만 쉽게 말해 데이터화 시키는 것이다.
즉, 하나의 JVM에서는 메모리 주소를 참조하며 공유하는데,
두 개 이상의 JVM에서는 서로 메모리 주소도 다르며 메모리에 다른 값이 이미 있을 가능성이 높다.
그래서 메모리 주소가 아닌 실제 값을 데이터화 하여 전송해야 같은 값을 공유할 수 있다.
class Person implements Serializable /* 직렬화 필수 조건 */{
private String name;
private int age;
private transient String ssn; // transient 선언으로 직렬화에서 제외
private LoginInfo lInfo; // 객체 타입이라 직렬화 필요
}
클래스의 변경 여부를 파악하기 위한 유일키
약간 DB의 PK와 비슷하다고 생각하면 편하다.
직렬화를 구현한 객체의 버전이 달라질 수 있다.(직렬화 할 요소가 늘었다던지, 줄었다던지 등등)
이때 같은 UID인 객체를 불러오면 런타임 예외가 나게된다.
직렬화 할 때의 UID와 역직렬화 할 때의 UID가 다르면 예외 발생
그래서 변경할 때마다 새로운 UID를 만들어 버전을 관리하기 할 수 있다.
public class Main {
static class Road{
int from;
int to;
int ramp;
public Road(int from, int to, int ramp) {
super();
this.from = from;
this.to = to;
this.ramp = ramp;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
long min = 0;
long max = 0;
int[] parents = new int[n + 1];
for(int i = 0; i < n + 1; i++) {
parents[i] = i;
}
List<Road> list = new ArrayList<>();
for(int i = 0; i < m + 1; i++) {
st = new StringTokenizer(br.readLine());
int from = Integer.parseInt(st.nextToken());
int to = Integer.parseInt(st.nextToken());
int ramp = Integer.parseInt(st.nextToken());
list.add(new Road(from, to, ramp));
}
// 1. 가장 많은 피로도
Collections.sort(list, new Comparator<Road>() {
@Override
public int compare(Road o1, Road o2) {
if(o1.ramp == o2.ramp) {
return o1.from - o2.from;
}
return o1.ramp - o2.ramp;
}
});
for(Road road : list) {
if(!isSameParent(parents, road.from, road.to)) {
union(parents, road.from, road.to);
if(road.ramp == 0) min++;
}
}
// 2. 가장 적은 피로도
for(int i = 0; i < n + 1; i++) {
parents[i] = i;
}
Collections.sort(list, new Comparator<Road>() {
@Override
public int compare(Road o1, Road o2) {
if(o2.ramp == o1.ramp) {
return o2.ramp - o1.ramp;
}
return o2.ramp - o1.ramp;
}
});
for(Road road : list) {
if(!isSameParent(parents, road.from, road.to)) {
union(parents, road.from, road.to);
if(road.ramp == 0) max++;
}
}
long ans = min * min - max * max;
System.out.println(ans);
}
static boolean isSameParent(int[] parents, int from, int to) {
from = findParent(parents, from);
to = findParent(parents, to);
return from == to;
}
static int findParent(int[] parents, int from) {
if(from != parents[from]) {
return parents[from] = findParent(parents, parents[from]);
}
return parents[from];
}
static void union(int[] parents, int from, int to) {
from = findParent(parents, from);
to = findParent(parents, to);
parents[to] = from;
}
}
풀이 요약
전형적인 MST 알고리즘인 것 같다.
라고 말하기엔 수많은틀렸습니다
를 봤는데, 크루스칼 알고리즘엔 문제가 없어서 사소한 코드 하나하나 고칠 때마다 제출을 했다.
결과적으로 변수 하나를 잘 못 적어서 난 이슈였다..문제 풀이시 주의 사항
1. 0(입구)부터 시작한다.
2. 오르막이 0, 내리막이 1