1. 플로이드 워셜

2. for loop 은 k i j

3. i -> j 를 가는데 i -> k -> j 를 가면 더 싸면 그 비용으로 체인지

문제

월드컵 축구의 응원을 위한 모임에서 회장을 선출하려고 한다. 이 모임은 만들어진지 얼마 되지 않았기 때문에 회원 사이에 서로 모르는 사람도 있지만, 몇 사람을 통하면 모두가 서로 알 수 있다. 각 회원은 다른 회원들과 가까운 정도에 따라 점수를 받게 된다.

예를 들어 어느 회원이 다른 모든 회원과 친구이면, 이 회원의 점수는 1점이다. 어느 회원의 점수가 2점이면, 다른 모든 회원이 친구이거나 친구의 친구임을 말한다. 또한 어느 회원의 점수가 3점이면, 다른 모든 회원이 친구이거나, 친구의 친구이거나, 친구의 친구의 친구임을 말한다.

4점, 5점 등은 같은 방법으로 정해진다. 각 회원의 점수를 정할 때 주의할 점은 어떤 두 회원이 친구사이이면서 동시에 친구의 친구사이이면, 이 두사람은 친구사이라고 본다.

회장은 회원들 중에서 점수가 가장 작은 사람이 된다. 회장의 점수와 회장이 될 수 있는 모든 사람을 찾는 프로그램을 작성하시오.

입력

입력의 첫째 줄에는 회원의 수가 있다. 단, 회원의 수는 50명을 넘지 않는다. 둘째 줄 이후로는 한 줄에 두 개의 회원번호가 있는데, 이것은 두 회원이 서로 친구임을 나타낸다. 회원번호는 1부터 회원의 수만큼 붙어 있다. 마지막 줄에는 -1이 두 개 들어있다.

출력

첫째 줄에는 회장 후보의 점수와 후보의 수를 출력하고, 두 번째 줄에는 회장 후보를 오름차순으로 모두 출력한다.


1. 입력값이 1 2 면 [1][2] = -1 [2][1] = 1

2. Floyd-Warshall 실행

3. 그대로 출력


아이디어만 있다면 간단한 문제


기존 floyd-warshall 알고리즘과 동일하게

1. i > j 를 갱신하고 싶다.

2. 어떻게 하지?

3. i > k > j 가 되는경우

끝.

i -> j 를 갈 때,

i -> k -> j 를 가는게 더 짧으면 업데이트 한다.


floyd-warshall 의 아이디어다.


O(V^3)


다음 문제때, 조금 더 자세히 살펴보면서 증명까지 가능하면 해보겠다.


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


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

생각을 좀 해봤다.


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

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

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


다익스트라에 이어서 플로이드 워셜 알고리즘을 공부했다.


다익스트라를 모든 정점에서 돌리면 플로이드 워셜이 된다.

그런데 다익스트라는 음수 가중치를 가지는 간선이 있으면 안된다 한다.


플로이드 워셜은 모든 정점을 돌아보기 때문에 시간복잡도가 O(V^3)이다.



입력에서 중복값 확인을 해주니 정답이 됐다.


위키백과에 JAVA코드도 추가했다.



위키백과 JAVA

+ Recent posts