Repository navigation
34-kangrae-jo - #136
34-kangrae-jo#136
Conversation
g0rnn
left a comment
There was a problem hiding this comment.
์ค๋ ๊ธฐ๋ค๋ฆฌ์ จ์ฃ ? ใ ใ
์ ์ฒ์์ ๊ฒฝ๋ก๋ฅผ ๋์๋๊ธฐ๋ฉด์ ์์๊ฐ ์๋์ง ํ์ธํ๋ ค ํ์ต๋๋ค. ๊ทธ๋ฐ๋ฐ ์๊ฐํด๋ณด๋ ์ฌ์ดํด์ด ์๊ธฐ๋ฉด ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ ์๊ฐ ์์ฃ . ๋ฌดํ๋๋ก ์์ฑ๋์์์.
๊ทธ๋์ ๋ต์ ์ฐธ๊ณ ํ์ต๋๋ค. ๋ฒจ๋ง ํฌ๋ ๊ฐ์์๋ฃ๋ฅผ ๋ค์ ๋ณด๋ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๊ตฌํ๋ ๊ฒ ๋ฟ๋ง ์๋๋ผ ์์ ์ฌ์ดํด์ ํ์ธํ ์๊ฐ ์๋๊ตฐ์. ์คํ๋ ค ์์ ์ฌ์ดํด์ ํ์ธํ๋ ๋ฐฉ๋ฒ์ฒ๋ผ ๋๊ปด์ก์ต๋๋ค. ๊ทธ๋์ ๋ค์ต์คํธ๋ผ์ ๊ฐ๋ ค์ ธ์ ์ ๊ฒฝ์ฐ์ง ์์ ๋ ์์ธ๋ฐ ๊ฝค ๊ด์ฐฎ์ ์น๊ตฌ์๋ค๋๊ฑธ ์๊ฒ ๋์์ด์.
๊ตฌํ์ cpp๊ณผ ๋ค๋ฅด๊ฒ ์ข ๋ณต์กํฉ๋๋ค.. ๋ณต์กํ๋ค๊ธฐ ๋ณด๋จ ๋ณด์ผ๋ฌ ํ๋ ์ดํธ๊ฐ ์ข ๋ง์์.
package beakjoon;
import java.io.*;
import java.util.*;
public class Sol1865 {
private static int tc = 0;
public static void main(String[] args) throws IOException {
readInput();
}
private static void readInput() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
tc = Integer.parseInt(br.readLine());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < tc; i++) {
st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int w = Integer.parseInt(st.nextToken());
List<Edge> edges = new ArrayList<>();
for (int j = 0; j < m; j++) {
st = new StringTokenizer(br.readLine());
int s = Integer.parseInt(st.nextToken());
int e = Integer.parseInt(st.nextToken());
int t = Integer.parseInt(st.nextToken());
edges.add(new Edge(s, e, t));
edges.add(new Edge(e, s, t));
}
for (int j = 0; j < w; j++) {
st = new StringTokenizer(br.readLine());
int s = Integer.parseInt(st.nextToken());
int e = Integer.parseInt(st.nextToken());
int t = Integer.parseInt(st.nextToken());
edges.add(new Edge(s, e, -t));
}
sb.append(hasNegativeCycle(edges, n) ? "YES" : "NO").append('\n');
}
System.out.println(sb.toString());
br.close();
}
private static boolean hasNegativeCycle(List<Edge> edges, int n) {
int[] dist = new int[n + 1]; // 1์์ ์ถ๋ฐ!
Arrays.fill(dist, 0);
for (int i = 1; i < n; i++) {
boolean updated = false;
for (Edge e : edges) {
if (dist[e.to] > dist[e.from] + e.time) {
dist[e.to] = dist[e.from] + e.time;
updated = true;
}
}
if (!updated) break;
}
for (Edge e : edges) {
if (dist[e.to] > dist[e.from] + e.time) return true;
}
return false;
}
static class Edge {
int from;
int to;
int time;
Edge(int f, int t, int time) {
from = f;
to = t;
this.time = time;
}
}
}๊ทผ๋ฐ ํน์ดํ๊ฒ ์ด๋ ์์ ์์ ์ฌ์ดํด์ ์ฐพ๋๋ฐ์๋ง ํนํ๋์ด ์๋๋ผ๊ตฌ์. ๊ทธ๋์ ์์ ์ฌ๋ถ์ ์๊ด์์ด ์ฌ์ดํด์ ์ฐพ์ ์ ์๋ ๋ฐฉ๋ฒ์ด ๊ถ๊ธํด์ก์ต๋๋ค.
์ฐพ์๋ณด๋ ์ด๋ ์ ๋์จ ํ์ธ๋๋ฅผ ์ด์ฉํ๋๋ผ๊ตฌ์. ์ด๊ฒ๋ ๋ฒจ๋ง ํฌ๋์ ๋น์ทํ๊ฒ ์ฃ์ง๋ณ๋ก ์ํํฉ๋๋ค. ์ฃ์ง๋ฅผ ์ํํ๋ฉฐ u, v๋ฅผ union(์งํฉ์ ๊ฒฐํฉ)ํ๋ค๊ฐ u์ v์ root parent๊ฐ ๊ฐ์ผ๋ฉด ์ฌ์ดํด๋ก ํ๋ณํฉ๋๋ค. ์๋์ฝ๋๋ฅผ ์ ์ด๋ํ ๋ ์ฐธ๊ณ ํ์์กฐ
for (auto u, v : edges) {
if (!union(u, v)) {
hasCycle = true;
break;
}
}
union(int u, int v) {
parent_u = findParent(u);
parent_v = findParent(v);
if (parent_u == parent_v) return false; // ์ฌ์ดํด ๋ฐ์
parent[u] = v; // ์๋ก ๋ค๋ฅธ ์งํฉ์ด๋ฏ๋ก ๋ ์งํฉ์ ํฉ์นจ
return true;
}
๐ ๋ฌธ์ ๋งํฌ
[์ํ]
โ๏ธ ์์๋ ์๊ฐ
40m ~ 1h
โจ ์๋ ์ฝ๋
์ ๋ ์ด ๋ฌธ์ ๋ฅผ ์ฝ๊ณ "์์ ์ฌ์ดํด"์ด ์์ผ๋ฉด YES๊ณ , ์๋๋ผ๋ฉด NO๋ผ๊ณ ์๊ฐํ๊ณ ๊ทธ๋ ๊ฒ ์ ๊ทผํ์ต๋๋ค.
๊ทธ๋์ ๋ฑ ํ๋์ ์๊ณ ๋ฆฌ์ฆ์ด ๋ ์ค๋ฅด๋๋ผ๊ตฌ์.
๋ฐ๋ก ๋ฒจ๋ง ํฌ๋ ์๊ณ ๋ฆฌ์ฆ์ด์ฃ .
๋ฒจ๋ง ํฌ๋๋ ์ต๋จ ๊ฒฝ๋ก ์๊ณ ๋ฆฌ์ฆ ์ค ํ๋์ด๋ฉฐ, ์์ ๊ฐ์ค์น๊ฐ ์๋ ๊ทธ๋ํ์์๋ ์ฌ์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค.
๊ทธ๋ฌ๋ ๊ตฌํ์ ํ๋ ๋ฐฉ๋ฒ์ ๊น๋จน์ด์... ๋ค์ ๊ณต๋ถํ๊ณ ํ์ด๋ณด๋๋ผ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ ธ์ต๋๋ค.
๋ฒจ๋ง ํฌ๋ ์๊ณ ๋ฆฌ์ฆ์ ์์ด๋์ด๋ ๋ค์๊ณผ ๊ฐ์์.
์ด๋์ ๊ธ๋ก ๋ณด๋๊น ์ดํด๊ฐ ์ฝ์ฃ ?
์์ relaxation์ด๋ผ๋ ํํ์ด ๋์๋๋ฐ '์ํ'๋ผ๊ณ ํฉ๋๋ค.
๋ชจ๋ ๊ฐ์ u ->{ v, w } ์ ๋ํด์,
ํ๋ ๊ฒ์ ๋งํฉ๋๋ค.
์ ์ ์ด N, ๊ฐ์ ์ด M์ผ๋
์ด ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐ๋ณต์ก๋๊ฐ O(NM) ์ ๋๋ค.
๋งค ๋ผ์ด๋๋ง๋ค ๋ชจ๋ ๊ฐ์ M๊ฐ๋ฅผ ํ๊ณ ๊ทธ๊ฑธ N-1๋ฒ ์ ๋ ๋ฐ๋ณตํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋ค์ต์คํธ๋ผ๋ณด๋ค ๋๋ฆฌ์ง๋ง ์์ ๊ฐ์ค์น๋ ์ฒ๋ฆฌ ๊ฐ๋ฅํ๋ค๋ ์ฅ์ ์ด ์์ฃ .
(์ฐธ๊ณ ๋ก pq๋ก ๊ตฌํํ ๋ค์ต์คํธ๋ผ๋ O((N + M) log N) ์ด๋ผ๊ณ ํฉ๋๋ค.)
์ด๋ฒ๋ฌธ์ ๋ ๋ฒจ๋ง ํฌ๋๋ฅผ boolํ์ ์ผ๋ก return ํ๋ ๊ฒ์ ๊ตฌํํ ์ ์๋ค๋ฉด ํ ์ ์๋ ๋ฌธ์ ์๋ค์.
๊ฐ์ฌํฉ๋๋ค.
๐ ์๋กญ๊ฒ ์๊ฒ๋ ๋ด์ฉ
๋ฒจ๋ง ํฌ๋ ์๊ณ ๋ฆฌ์ฆ์ ์๊ฒ ๋์๋ค.
์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ๋ ๊ธฐ๋ณธ ์ฐ์ฐ์ธ relaxation์ ๋ํด์๋ ์๊ฒ ๋์๋ค.
ใฑใ ใ ๊ต์๋์ ์๋ฃ์ ๋๋ค.
๋ณด๊ณ ๊ตฌํ์ ํ๊ฑด ์๋์ง๋ง ๋ฒจ๋ง ํฌ๋๋ฅผ ์ดํดํ๋ ๊ฒ์ ๋์์ด ๋์ด์ ์ฒจ๋ถํฉ๋๋ค.
์๋ฃ์์๋ N-1๋ฒ์ ๊ณ ์ ์ผ๋ก relaxํ๊ณ ,
์ดํ์ ํ๋ฒ์ฉ ๋ relaxํด์ true false๋ฅผ ํ๋ณํ๋ ๊ตฐ์.
์ ๋ N๋ฒ ๋ฐ๋ณตํ๋๋ฐ, ์๋ก relax๋๋ ์์ ์ด N๋ฒ์งธ์ด๋ฉด return true ํ๋๋ก ํ์ต๋๋ค.
์ทจํฅ์ ๋ง๊ฒ ๊ตฌํํ์๋ฉด ๋ ๊ฒ ๊ฐ๋ค์.