๊ด€๋ฆฌ ๋ฉ”๋‰ด

Unfazedโ—๏ธ๐ŸŽฏ

[Java] ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ, DFS | ๋ฐฑ์ค€ 2458 ํ‚ค ์ˆœ์„œ ๋ณธ๋ฌธ

๋ฌธ์ œ ํ•ด๊ฒฐ (PS)/์ฝ”ํ…Œ TIL

[Java] ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ, DFS | ๋ฐฑ์ค€ 2458 ํ‚ค ์ˆœ์„œ

9taetae9 2024. 11. 3. 10:59
728x90

https://www.acmicpc.net/problem/2458

 
์ ‘๊ทผ ๋ฐฉ๋ฒ•
 
์ฒซ์ ‘๊ทผ(์‹คํŒจ)
๋ฌธ์ œ ์œ ํ˜•์„ ๋ณด์ง€ ์•Š๊ณ  ํ’€์–ด๋ณด์•˜์„ ๋•Œ ์ผ์ฐจ์› ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค๊ณ 
๊ด€๊ณ„๊ฐ€ ์ฃผ์–ด์งˆ ๋•Œ, a > b์ธ ๊ฒฝ์šฐ, ๋ฐฐ์—ด์—์„œ b๋ณด๋‹ค ํฐ ํ•™์ƒ ์ˆ˜๋ฅผ a์˜ ์œ„์น˜์— ๋ˆ„์ ํ•˜์—ฌ ๊ธฐ๋ก
๋งŒ์•ฝ ์ด๋ฏธ ๋ˆ„์ ๋œ ๊ฐ’์ด ํฌ๋‹ค๋ฉด ํ•ด๋‹น ๊ด€๊ณ„๋Š” ๋ฌด์‹œํ•จ
๋ฐฐ์—ด์˜ ์ตœ์ข… ๊ฐ’์ด ์œ ์ผ(unique)ํ•˜๋‹ค๋ฉด, ํ•ด๋‹น ํ•™์ƒ์˜ ์ˆœ์œ„๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์€ ๊ฐ„์ ‘ ๊ด€๊ณ„ ํ™•์ธ ๋ถˆ๊ฐ€ ๋“ฑ์˜ ์ด์œ ๋กœ ์‹ค์ œ ์ˆœ์œ„๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์•˜๋‹ค.
 
์ฒซ๋ฒˆ์งธ ๋ฐฉ๋ฒ•(ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ) 
๋ฌธ์ œ ์œ ํ˜•์ด ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ์ธ ๊ฒƒ์„ ํ™•์ธํ•œ ๋’ค ํ’€์–ด๋ณด์•˜๋‹ค.
์ฒ˜์Œ์—” int[] ๋ฐฐ์—ด๋กœ ํ’€์ดํ–ˆ๋‹ค๊ฐ€ ์ž์‹ ๋ณด๋‹ค ํฐ ์‚ฌ๋žŒ์„ true๋กœ ์ฒดํฌํ•˜๋Š” boolean[] ๋ฐฐ์—ด๋กœ ๋ฐ”๊พธ์–ด์„œ ์ฝ”๋“œ๋ฅผ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());

boolean[][] H = new boolean[N][N];

for(int i=0; i < M; i++){
    st = new StringTokenizer(br.readLine());
    int u1 = Integer.parseInt(st.nextToken());
    int u2 = Integer.parseInt(st.nextToken());

    H[u1-1][u2-1] = true;
}

์•„๋ž˜์™€ ๊ฐ™์ด ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•œ๋‹ค.
k๋ฅผ ๊ธฐ์ค€์œผ๋กœ i ์™€ k ์˜ ๋Œ€์†Œ ๊ด€๊ณ„(i์˜ ํ‚ค<j์˜ ํ‚ค)๊ฐ€ ์ •ํ•ด์ง„๋‹ค๋ฉด H[i][j] = true๋กœ ์„ค์ •ํ•œ๋‹ค.

for(int k=0; k < H.length; k++) {
    for (int i = 0; i < H.length; i++) {
        if(i == k) continue;
        for (int j = 0; j < H.length; j++) {
            if(H[i][k] && H[k][j]) {
                H[i][j] = true;
            }
        }
    }
}

์ž์‹ ์ด ํ‚ค๊ฐ€ ๋ช‡ ๋ฒˆ์งธ์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ๋Š” ํ•™์ƒ์€ ์ž์‹ ๋ณด๋‹ค ๋ช‡๋ช…์ด ํฐ์ง€, ์ž์‹ ๋ณด๋‹ค ๋ช‡๋ช…์ด ์ž‘์€์ง€ ์ •ํ™•ํžˆ ์…€ ์ˆ˜ ์žˆ๋Š” ํ•™์ƒ์ด๋‹ค.
N๋ช…์˜ ํ•™์ƒ์ด ์กด์žฌํ•œ๋‹ค๋ฉด,i ๊ธฐ์ค€์œผ๋กœ ์„ค๋ช…ํ•˜๋ฉด H[i][j](์ž์‹ ๋ณด๋‹ค ํฐ ํ•™์ƒ ์ˆ˜) + H[j][i](์ž์‹ ๋ณด๋‹ค ์ž‘์€ ํ•™์ƒ ์ˆ˜) == N-1 ์ด ๋˜์–ด์•ผ ์œ„ ์กฐ๊ฑด์„ ๋งŒ์กฑ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
์ด๋ฅผ ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

int answer = 0;
for(int i=0; i < H.length; i++){
    int cnt=0;
    for(int j=0; j < H.length; j++){
        if(i==j) continue;
        if(H[i][j] || H[j][i]){
            cnt++;
        }
    }
    if(cnt==N-1) answer++;
}

์ตœ์ข…์ ์œผ๋กœ answer๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ์ •๋‹ต์ด ๋œ๋‹ค.
 
์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๋Š” ์‹œ๊ฐ„์ด 530ms ์ •๋„ ๋Œ€์˜€๋‹ค.
๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์ œ์ถœํ•œ ์ฝ”๋“œ๋“ค ์ค‘ ์‹œ๊ฐ„์ด ์งง์€ ์ฝ”๋“œ๋ฅผ ์œ„์ฃผ๋กœ ์‚ดํŽด๋ณด๋‹ˆ DFS๋กœ ์ ‘๊ทผํ•œ ํ’€์ด๊ฐ€ ๋งŽ์•„์„œ DFS๋กœ ๋‹ค์‹œ ๊ตฌํ˜„ํ•ด๋ณด์•˜๋‹ค.
 
๋‘๋ฒˆ์งธ ๋ฐฉ๋ฒ•(DFS, ๊นŠ์ด์šฐ์„ ํƒ์ƒ‰)
์šฐ์„  DFS๋ฐฉ์‹์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐฉ๋ฌธํ•œ ํ•™์ƒ ์ฒดํฌ๋ฅผ ์œ„ํ•œ boolean ๋ฐฐ์—ด์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

H = new boolean[N][N];
visited = new boolean[N];

for (int i = 0; i < M; i++) {
    st = new StringTokenizer(br.readLine());
    final int u1 = Integer.parseInt(st.nextToken());
    final int u2 = Integer.parseInt(st.nextToken());
    H[u1-1][u2-1] = true;
}

๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  ํ•™์ƒ์— ๋Œ€ํ•ด dfs๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. (๋ฐฉ๋ฌธ๋œ ํ•™์ƒ ์ œ์™ธ)

for (int i = 0; i < N; i++) {
    if (visited[i])
        continue;
    dfs(i);
}

dfs๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ˜„๋œ๋‹ค. s๋ฅผ ์‹œ์ž‘ ํ•™์ƒ์œผ๋กœ ๋‘๊ณ , H[s][i](i๊ฐ€ s๋ณด๋‹ค ํ‚ค๊ฐ€ ํผ)์ด true๋ผ๋ฉด i์— ๋Œ€ํ•ด dfs๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•œ๋‹ค.
์ด๋ ‡๊ฒŒ s ๋ณด๋‹ค ํฐ ํ•™์ƒ์„ ๊ผฌ๋ฆฌ์— ๊ผฌ๋ฆฌ๋ฅผ ๋ฌด๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ชจ๋‘ ์ฐพ์€ ๋’ค, H[s][j](s๋ณด๋‹ค ํฐ j)์— ์ง์ „ dfs(i) ํ˜ธ์ถœ๋กœ ์–ป์€ H[i][j](j๊ฐ€ i๋ณด๋‹ค ํผ)๋ฅผtrue์ผ ๊ฒฝ์šฐ ๊ฐฑ์‹ ํ•ด์ค€๋‹ค.
if(H[s][i]) // i ๊ฐ€ s๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ (s < i) 
dfs(i) // i์— ๋Œ€ํ•ด i ๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ ์ฐพ๊ธฐ ์œ„ํ•ด ๋‹ค์‹œ dfs ํ˜ธ์ถœ  => ๊ทธ๋ ‡๊ฒŒ ํ˜ธ์ถœํ•ด์„œ i ํ–‰์— ๋Œ€ํ•œ ๋ชจ๋“  ์ •๋ณด ๊ฐฑ์‹  (๊ทธ๋ ‡๊ฒŒ iํ–‰์— ๋ˆ„์ ๋œ true๋Š” ์ง์ „์— dfs(i)๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋งŒ๋“  H[s][i] ์ฆ‰ sํ–‰์— ๋ชจ๋‘ true๋กœ ์ถ”๊ฐ€์‹œ์ผœ์•ผํ•จ.
 
H[s][j] = H[i][j]; // j๊ฐ€ i๋ณด๋‹ค ํฌ๋‹ค๋ฉด j๋Š” s๋ณด๋‹ค๋„ ํฌ๊ธฐ ๋•Œ๋ฌธ

public static void dfs(final int s) {
    if (visited[s])
        return;

    for (int i = 0; i < N; i++) {
        if (H[s][i]) {
            dfs(i);
            for (int j = 0; j < N; j++) {
                if(!H[s][j] && H[i][j]) {
                    H[s][j] = H[i][j];
                }
            }
        }
    }
    visited[s] = true;
}

์ด๋ ‡๊ฒŒ ๋ชจ๋“  ํ•™์ƒ์— ๋Œ€ํ•ด dfs ํ˜ธ์ถœ์ด ์™„๋ฃŒ ๋˜์—ˆ๋‹ค๋ฉด ์ž์‹ ๋ณด๋‹ค ํฐ ํ•™์ƒ๋“ค์— ๋Œ€ํ•ด ๊ฐ ํ–‰์—์„œ true๋“ค์ด ๋ชจ๋‘ ๊ฐฑ์‹ ๋œ ์ƒํƒœ์ด๋‹ค.
H[i][j] : i๋ณด๋‹ค j๊ฐ€ ํผ, H[j][i] : j๋ณด๋‹ค i๊ฐ€ ํผ => ์ด ๋‘˜์ค‘ํ•˜๋‚˜๋Š” true ์—ฌ์•ผ ๋Œ€์†Œ๋น„๊ต๊ฐ€ ๊ฐ€๋Šฅํ•จ
์šฐ๋ฆฌ๋Š” ์ •ํ™•ํžˆ ์ž์‹ ๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ์ž‘์€ ๊ฒƒ์„ ์•„๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๊ณ  ์ด๊ฒƒ์€ ์ฒซ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•๊ณผ ๋™์ผํ•˜๊ฒŒ N-1์ธ์ง€ ์ฒดํฌํ•˜๋ฉด ๋œ๋‹ค.

int answer = 0;
for (int i = 0; i < N; i++) {
    int sum = 0;
    for (int j = 0; j < N; j++) {
        if(H[i][j] || H[j][i]) sum++;
    }
    if (sum == N - 1)
        answer++;
}

 
 

 
ํ”Œ๋กœ์ด๋“œ์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ–ˆ์„ ๋•Œ๋ณด๋‹ค dfs๋กœ ์ ‘๊ทผํ–ˆ์„ ๋•Œ ๋” ์ข‹์€ ์„ฑ๋Šฅ์„ ๋ณด์˜€๋Š”๋ฐ ๊ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋ณต์žก๋„๋ฅผ ๊ณ ๋ คํ•ด๋ณด๋ฉด
 
๋ฐฉ๋ฒ• 1 (ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ)

  • 3์ค‘ ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉ
  • ์ „์ฒด ์‹œ๊ฐ„ ๋ณต์žก๋„: O(N^3), ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌ์†Œํ•˜๋”๋ผ๋„ O(N^3)๋กœ ๊ณ ์ •
  • ๊ทธ๋ž˜ํ”„์˜ ๋ฐ€์ง‘๋„(ํฌ์†Œํ–‰๋ ฌ, ๋ฐ€์ง‘ํ–‰๋ ฌ)์™€ ์ƒ๊ด€์—†์ด ๋ชจ๋“  ๋…ธ๋“œ ์Œ์„ ๊ณ ๋ คํ•˜๋Š” ํ”Œ๋กœ์ด๋“œ์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ํŠน์„ฑ
  • ๊ณต๊ฐ„ ๋ณต์žก๋„: O(N^2)

๋ฐฉ๋ฒ• 2 (DFS)

  • DFS๋ฅผ N๋ฒˆ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ฐ DFS์—์„œ ์ตœ๋Œ€ N๊ฐœ์˜ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ
  • ์ „์ฒด ์‹œ๊ฐ„ ๋ณต์žก๋„: O(N * (N^2)) 
  • ์ตœ์„  : O(N^2)-H[s][i]๊ฐ€ ๋ชจ๋‘ false๋ผ๋ฉด N๋ฒˆ๋งŒ ์ˆœํšŒ
  • ์ตœ์•… : O(N^3)
  • ๊ณต๊ฐ„ ๋ณต์žก๋„: O(N^2) (์ธ์ ‘ ํ–‰๋ ฌ) + O(N) (๋ฐฉ๋ฌธ ๋ฐฐ์—ด)

์œ„์˜ ์ด์œ ๋•Œ๋ฌธ์— DFS ์ ‘๊ทผ๋ฒ•์ด ์ด ๋ฌธ์ œ์—์„œ ๋” ์ข‹์€ ์„ฑ๋Šฅ์„ ๋ณด์ธ ๊ฒƒ ๊ฐ™๋‹ค. ํ‰๊ท ์ ์ธ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ DFS์— ์œ ๋ฆฌํ•˜์ง€ ์•Š์•˜์„๊นŒ ์ƒ๊ฐํ•ด๋ณธ๋‹ค.
 
DFS ์ ‘๊ทผ๋ฒ•์€ N์ด ์ž‘๊ฑฐ๋‚˜ ๊ทธ๋ž˜ํ”„๊ฐ€ ํฌ์†Œํ•œ ๊ฒฝ์šฐ์—๋Š” ์ข‹์€ ์„ฑ๋Šฅ์„ ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, N์ด ์ปค์ง€๊ฑฐ๋‚˜ ๊ทธ๋ž˜ํ”„๊ฐ€ ๋ฐ€์ง‘๋˜์—ˆ์„ ๊ฒฝ์šฐ DFS ํ˜ธ์ถœ๋งˆ๋‹ค ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  ๊ด€๊ณ„๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ณผ์ •์—์„œ ์ถ”๊ฐ€์ ์ธ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค.
๋ฐ˜๋ฉด, ํ”Œ๋กœ์ด๋“œ์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ฒฝ์šฐ ์ค‘๋ณต ์—ฐ์‚ฐ ์—†์ด ๋ชจ๋“  ๋…ธ๋“œ ์Œ์„ ์ผ์ •ํ•˜๊ฒŒ ํ•œ ๋ฒˆ์”ฉ๋งŒ ํ™•์ธํ•˜๋ฏ€๋กœ ๊ณผ๋„ํ•œ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์ ๋‹ค.
 
 
 
๋А๋‚€์  : 
dfs๋กœ ํ’€์–ด๋ณด๋ฉด์„œ ๋А๋‚€ ๊ฒƒ์ด ์žˆ๋Š”๋ฐ, ๋ฌธ์ œ๋ฅผ ํ’€๊ธฐ ์œ„ํ•ด ๋‚ด๊ฐ€ ์ง์ ‘ ์ธ์ ‘ํ–‰๋ ฌ์„ ์†์œผ๋กœ ๊ทธ๋ ค๋ณด๊ณ  ํ’€์—ˆ์„ ๋•Œ, DFS์˜ ๋ฐฉ๋ฒ•์œผ๋กœ ํ’€๊ณ  ์žˆ์—ˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
ํ•˜์ง€๋งŒ ์ •์ž‘ ์ฝ”๋“œ๋กœ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” ์ „ํ˜€ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ์ ‘๊ทผํ–ˆ๋‹ค. ๋‚ด๊ฐ€ ์†์œผ๋กœ ํ’€์—ˆ์„ ๋•Œ(๋ณธ๋Šฅ์ ์ธ?)ํ’€์ด๋ฅผ ์ž˜ ์ผ€์น˜ํ•˜์•ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์ ์ ˆํžˆ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฐ๊ฐ์„ ํ‚ค์›Œ์•ผ๋ ๊ฑฐ ๊ฐ™๋‹ค.
๋˜ ํ”Œ๋กœ์ด๋“œ์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ 6์ผ์ „์— ์ฒ˜์Œ ์ ‘ํ–ˆ์„ ๋•Œ ๋ญ”๊ฐ€ ์• ๋งคํ•˜๊ฒŒ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์•„ ๋‹ต๋‹ตํ–ˆ๋Š”๋ฐ, ์ง€๋‚œ 6์ผ๋™์•ˆ ์ตœ๋‹จ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•˜๊ณ  ๊ด€๋ จ๋œ ๋ฌธ์ œ 3,4๊ฐœ์ •๋„๋ฅผ ๊ธธ๊ฒŒ ๊ณ ๋ฏผํ•ด๋ณด๋‹ˆ ์ ์  ๋‚˜์˜ ๊ฒƒ์ด ๋˜๋Š”๋“ฏํ•œ ๋А๋‚Œ์ด ๋“ค๊ณ  ์žˆ๋‹ค. ํ•˜๋ฃจ ํ•œ๋ฌธ์ œ๋งŒ ํ’€์–ด๋„ ๊นŠ๊ฒŒ ๊ณ ๋ฏผ์„ ํ•ด๋ณด๋Š” ๊ฒƒ์ด ๋” ๋„์›€๋˜๋Š”๊ฑฐ ๊ฐ™์•„ ์ฝ”ํ…Œ์— ์ž์‹ ๊ฐ์ด ์ƒ๊ธธ ๋•Œ๊นŒ์ง€ ๊พธ์ค€ํžˆ ๋งค์ผ ํ•œ๋ฌธ์ œ์”ฉ ๊นŠ๊ฒŒ ๊ณ ๋ฏผํ•ด๋ด์•ผ๊ฒ ๋‹ค.

728x90