1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
 
public class Main {
    // 타잔 알고리즘은 위상 정렬을 이용한 방법으로 생성되는 SCC들은 위상정렬의 역순으로 생성된다.
    // 위상정렬 : 방향성을 거스르지 않게 정점들을 나열하는 알고리즘.
    static int V, E, discover[], scc[], c, r;
    static Stack<Integer> stk = new Stack<Integer>();
    static ArrayList<ArrayList<Integer>> vt = new ArrayList<ArrayList<Integer>>();;
    static ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();;
 
    static int dfs(int here) {
        discover[here] = c++// c는 방문 표시? 0<= c < V
        int ret = discover[here]; // 현재 discover[here]==-1 상태로 이값에 자기의 방문 순서를 넣어준다.
        System.out.println(here+" 진입 , discover = "+ret);
        stk.push(here); // dfs 호출 순서에 따라 정점을 stack에 push
        for (int there : vt.get(here)) // 자신이 탐색할 수 있는 정점 중 가장 높은 위치를 return
            if (discover[there] == -1// 아직 방문하지 않은 점이라면
                ret = Math.min(ret, dfs(there));
            else if (scc[there] == -1// 다음에 갈곳이 아직 scc를 이루지 않았다면
                ret = Math.min(ret, discover[there]);
        }
        if (ret == discover[here]) { // return된 값이 자기에게 할당된 discover와 같다면
            System.out.println(here+"일 때, scc로 묶는다."+" => discover["+here+"] = "+discover[here]+", scc["+here+"] = "+scc[here]+" ret = "+ret);
            ArrayList<Integer> tmp = new ArrayList<Integer>();
            while (true) {
                int t = stk.pop();
                System.out.println("pop = "+t);
                scc[t] = r; // r은 res의 크기(size) scc를 이루었다면 각 정점에 표시
                tmp.add(t);
                if (t == here) // 해당 정점이 나올때까지 pop하면서 모든 정점을 같은 scc로 묶는다.
                    break;
            }
            System.out.println(Arrays.toString(discover));
            System.out.println(Arrays.toString(scc));
            Collections.sort(tmp);
            res.add(tmp);
            r++;
        }
        System.out.println("return => discover["+here+"] = "+discover[here]+", scc["+here+"] = "+scc[here]);
        System.out.println();
        return ret;
    }
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        V = Integer.parseInt(st.nextToken());
        E = Integer.parseInt(st.nextToken());
 
        for (int i = 0; i <= V; i++)
            vt.add(new ArrayList<Integer>());
        for (int i = 0, a, b; i < E; i++) {
            st = new StringTokenizer(br.readLine());
            a = Integer.parseInt(st.nextToken());
            b = Integer.parseInt(st.nextToken());
            vt.get(a).add(b); // 간선 정보들을 저장
        }
 
        discover = new int[V + 1];
        scc = new int[V + 1];
        Arrays.fill(discover, -1);
        Arrays.fill(scc, -1);
 
        for (int i = 1; i <= V; i++) {
            if (discover[i] == -1)
                dfs(i);
        }
 
        Collections.sort(res, new Comparator<ArrayList<Integer>>() {
            @Override
            public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
                return o1.get(0- o2.get(0);
            }
        });
 
        StringBuilder sb = new StringBuilder();
        sb.append(r + "\n");
        for (int i = 0; i < r; i++) {
            for (int v : res.get(i))
                sb.append(v + " ");
            sb.append("-1\n");
        }
        System.out.println(sb);
        System.out.println(Arrays.toString(discover));
        System.out.println(Arrays.toString(scc));
        br.close();
    }
 
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
 
public class Main {
 
    static int C, N;
    static int cache[][] = new int[101][101];
    static String W, S;
 
    static int match(int w, int s) {
        if (cache[w][s] != -1)
            return cache[w][s];
        int ow = w, os = s;
 
        while (s < S.length() && w < W.length() && (W.charAt(w) == '?' || W.charAt(w) == S.charAt(s))) {
            ++w;
            ++s;
        }
        if (w == W.length())
            return cache[ow][os] = (s == S.length() ? 1 : 0);
        if (W.charAt(w) == '*')
            for (int skip = 0; skip + s <= S.length(); ++skip)
                if (match(w + 1, s + skip) == 1)
                    return cache[ow][os] = 1;
        return cache[ow][os] = 0;
    }
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        C = Integer.parseInt(br.readLine());
//        StringTokenizer st = null;
 
        ArrayList<String> result = new ArrayList<String>();
//        ArrayList<String> list = new ArrayList<String>();
        StringBuilder sb = new StringBuilder();
 
        for (int c = 0; c < C; c++) {
            W = br.readLine();
            N = Integer.parseInt(br.readLine());
            result.clear();
            
//            list.clear();
            for (int i = 0; i < N; i++) {
                for (int j= 0; j <= 100; j++)
                    Arrays.fill(cache[j], -1);
//                list.add(br.readLine());
                S = br.readLine();
                if(match(00)==1) {
                    result.add(S);
                }
            }
 
            Collections.sort(result);
            for (String word : result) {
                sb.append(word + "\n");
            }
        } // tc end
        System.out.println(sb);
 
        br.close();
    }
 
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs

정리해야함 코드도 내용도

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

 

2042번: 구간 합 구하기

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 회수이고, K는 구간의 합을 구하는 회수이다. 그리고 둘째 줄부터 N+1번째 줄까지 N개의 수가 주어진다. 그리고 N+2번째 줄부터 N+M+K+1번째 줄까지 세 개의 정수 a, b, c가 주어지는데, a가 1인 경우 b번째 수를 c로 바꾸고 a가 2인 경우에는 b번째 수부터 c번째 수까지의

www.acmicpc.net

 

[JAVA]

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n, m, k;
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        k = Integer.parseInt(st.nextToken());
        long a[] = new long[n];
        int h = (int) Math.ceil(Math.log10(n) / Math.log10(2));
        int tree_size = (1 << (h + 1));
        long tree[] = new long[tree_size];
        m += k;
        for (int i = 0; i < n; i++) {
            a[i] = Integer.parseInt(br.readLine());
        }
        init(a, tree, 1, 0, n - 1);

        StringBuilder sb = new StringBuilder();
        while (m-- > 0) {
            int t1, t2, t3;
            st = new StringTokenizer(br.readLine());
            t1 = Integer.parseInt(st.nextToken());
            if (t1 == 1) {
                long t4;
                t2 = Integer.parseInt(st.nextToken());
                t4 = Long.parseLong(st.nextToken());
                t2 -= 1;
                long diff = t4 - a[t2];
                a[t2] = t4;
                update(tree, 1, 0, n - 1, t2, diff);
            } else if (t1 == 2) {
                t2 = Integer.parseInt(st.nextToken());
                t3 = Integer.parseInt(st.nextToken());
                sb.append(sum(tree, 1, 0, n - 1, t2 - 1, t3 - 1) + "\n");
            }
        }
        System.out.println(sb);
        br.close();
    }

    static long init(long[] a, long[] tree, int node, int start, int end) {
        if (start == end)
            return tree[node] = a[start];
        else
            return tree[node] = init(a, tree, node * 2, start, (start + end) / 2)
                    + init(a, tree, node * 2 + 1, (start + end) / 2 + 1, end);
    }

    static void update(long[] tree, int node, int start, int end, int index, long diff) {
        if (index < start || index > end)
            return;
        tree[node] = tree[node] + diff;
        if (start != end) {
            update(tree, node * 2, start, (start + end) / 2, index, diff);
            update(tree, node * 2 + 1, (start + end) / 2 + 1, end, index, diff);
        }
    }

    static long sum(long[] tree, int node, int start, int end, int left, int right) {
        if (left > end || right < start)
            return 0;
        if (left <= start && end <= right)
            return tree[node];
        return sum(tree, node * 2, start, (start + end) / 2, left, right)
                + sum(tree, node * 2 + 1, (start + end) / 2 + 1, end, left, right);
    }

}

 

 

 


 

 

세그먼트 트리 (Segment Tree)

문제 배열 A가 있고, 여기서 다음과 같은 두 연산을 수행해야하는 문제를 생각해봅시다. 구간 l, r (l ≤ r)이 주어졌을 때, A[l] + A[l+1] + ... + A[r-1] + A[r]을 구해서 출력하기 i번째 수를 v로 바꾸기. A[i] = v 수행해야하는 연산은 최대 M번입니다. 세그먼트 트리나 다른 방법을 사용하지 않고 문제를 푼다면, 1번 연산을 수행하는데 O(N), 2번 연산을 수행하는데 O(1)이 걸리게 됩니다. 총 시간 복잡도는 O

www.acmicpc.net

 

'알고리즘 ' 카테고리의 다른 글

SCC - Tarjan (타잔 알고리즘)  (0) 2019.07.11
[알고스팟] WILDCARD - JAVA  (0) 2019.06.06
백준 1941 : 소문난 칠공주  (0) 2019.05.21
SCC - kosaraju  (0) 2019.05.21
Union-Find (유니온 파인드)  (0) 2019.05.17

설정 - Clang_format_fallback Style
Visual Studio
LLVM

 

https://murra.tistory.com/70

 

[VScode] Git, C, C++ Compile, Debugging using VS code (종합)

Windows 10 환경에서 Git, GitHub, Visual Studio Code, MinGW를 사용합니다. Windows 10 환경에서 Git, GitHub, Visual Studio Code, MinGW를 사용합니다. 목차 Visual Studio Code 설치 Git Vis..

murra.tistory.com

 

'이것저것' 카테고리의 다른 글

hosts 파일 수정하기  (0) 2020.11.07
[VSCODE] Terminal 실행  (0) 2020.05.02
[VSCODE] 글씨 폰트 설정  (0) 2019.05.18
알고리즘 c++ 하는방법  (0) 2019.05.17
[VSCODE] C++ 환경 구축  (0) 2019.05.17

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

 

1941번: 소문난 칠공주

총 25명의 여학생들로 이루어진 여학생반은 5*5의 정사각형 격자 형태로 자리가 배치되었고, 얼마 지나지 않아 이다솜과 임도연이라는 두 학생이 두각을 나타내며 다른 학생들을 휘어잡기 시작했다. 곧 모든 여학생이 ‘이다솜파’와 ‘임도연파’의 두 파로 갈라지게 되었으며, 얼마 지나지 않아 ‘임도연파’가 세력을 확장시키며 ‘이다솜파’를 위협하기 시작했다. 위기의식을 느낀 ‘이다솜파’의 학생들은 과감히 현재의 체제를 포기하고, ‘소문난 칠공주’를 결성하는 것이

www.acmicpc.net

[JAVA]
public class Main {
    static char[][] arr = new char[5][5];
    static int[] dy = { -1, 0, 0, 1 }, dx = { 0, -1, 1, 0 };
    static boolean[] b = new boolean[25];
    static int ret = 0;

    static boolean find(int y, int x) {
        boolean[][] check = new boolean[5][5];
        Queue<int[]> q = new LinkedList<>();
        check[y][x] = true;
        int vcnt = 1;
        q.offer(new int[] { y, x });
        while (!q.isEmpty()) {
            int[] s = q.poll();

            for (int i = 0; i < 4; i++) {
                int yy = s[0] + dy[i];
                int xx = s[1] + dx[i];
                if (0 <= yy && yy < 5 && 0 <= xx && xx < 5 && !check[yy][xx] && b[yy * 5 + xx]) {
                    vcnt += 1;
                    check[yy][xx] = true;
                    q.offer(new int[] { yy, xx });
                }
            }
        }
        return vcnt == 7 ? true : false;
    }

    static void dfs(int n, int pick, int sc) {
        sc += arr[n / 5][n % 5] == 'S' ? 1 : 0;
        b[n] = true;
        if (pick == 7) {
            if (sc >= 4) {
                if (find(n / 5, n % 5)) {
                    ret += 1;
                }
            }
        } else {
            for (int i = n + 1; i < 25; i++) {
                if (!b[i])
                    dfs(i, pick + 1, sc);
            }
        }
        b[n] = false;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        for (int i = 0; i < 5; i++) {
            String in = br.readLine();
            for (int j = 0; j < 5; j++) {
                arr[i][j] = in.charAt(j);
            }
        }

        for (int i = 0; i < 25; i++) {
            dfs(i, 1, 0);
        }

        System.out.println(ret);

        br.close();
    }
}

 

[C++]

 
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;

char arr[5][5];
bool b[25];
bool check[5][5];
int ret;
queue<pair<int, int>> q;
int dy[]{-1, 0, 0, 1}, dx[]{0, -1, 1, 0};

bool isFriends(int n)
{
    int y = n / 5;
    int x = n % 5;

    for (int i = 0; i < 5; i++)
    {
        fill(check[i], check[i] + 5, false);
    }
    int cnt = 1;
    check[y][x] = true;
    q.push(make_pair(y, x));
    while (!q.empty())
    {
        pair<int, int> p = q.front();
        q.pop();

        for (int i = 0; i < 4; i++)
        {
            y = p.first + dy[i];
            x = p.second + dx[i];
            if (0 <= y && y < 5 && 0 <= x && x < 5 && b[5 * y + x] && !check[y][x])
            {
                cnt++;
                check[y][x] = true;
                q.push(make_pair(y, x));
            }
        }
    }
    return cnt == 7 ? true : false;
}

void combine(int n, int pick, int s)
{
    b[n] = true;
    s += arr[n / 5][n % 5] == 'S' ? 1 : 0;
    if (pick == 7)
    {
        if (s >= 4 && isFriends(n))
            ret++;
    }
    else
    {
        for (int i = n + 1; i < 25; i++)
            combine(i, pick + 1, s);
    }
    b[n] = false;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    for (int i = 0; i < 5; i++)
        for (int j = 0; j < 5; j++)
            cin >> arr[i][j];

    for (int i = 0; i < 25; i++)
        combine(i, 1, 0);

    cout << ret;
    return 0;
}
 

 

조합을 통해서 7명을 뽑고 이다솜(S)파가 4명이상일 경우에만 7명이 인접해있는지 확인한다.

 


처음 풀때는 DFS를 통해서 7명을 찾을려고 해서 풀지 못했다. 옆 행렬인 경우 (2,1)에서 시작해서 (4,2)와 (4,5)를 포함하는 경우의 수가 존재한다. (4,5) 경우에는 DFS로 탐색이 가능하지만 (4,2) 경로를 포함한 경우는 (2,2) 좌표에서 십자가모양으로 퍼지기 때문에 DFS로 탐색할 수 없다. 

그래서 조합을 통해서 25개의 좌표 중에서 7개를 먼저 선택하는 방식으로 문제를 풀 수 있었다.

'알고리즘 ' 카테고리의 다른 글

[알고스팟] WILDCARD - JAVA  (0) 2019.06.06
백준 2042 : 구간 합 구하기 - 세그먼트 트리  (0) 2019.05.25
SCC - kosaraju  (0) 2019.05.21
Union-Find (유니온 파인드)  (0) 2019.05.17
Parametric search (파라메트릭 서치)  (0) 2019.05.16

SCC ( Strongly Connected Component )

 

강한 연결 요소, 집합 내에서 서로 왕복 가능한 최대 집합의 크기


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

 

2150번: Strongly Connected Component

첫째 줄에 두 정수 V(1≤V≤10,000), E(1≤E≤100,000)가 주어진다. 이는 그래프가 V개의 정점과 E개의 간선으로 이루어져 있다는 의미이다. 다음 E개의 줄에는 간선에 대한 정보를 나타내는 두 정수 A, B가 주어진다. 이는 A번 정점과 B번 정점이 연결되어 있다는 의미이다. 이때 방향은 A->B가 된다.

www.acmicpc.net

 

  1. 방향 그래프, 역방향 그래프, 스택을 준비한다.
  2. 방향 그래프를 사용하여 dfs를 수행하고, 끝나는 순서대로 스택에 push한다. (단, 모든 정점에 대해서 수행)
  3. 스택을 비울 때까지 pop을 하면서, 역방향 그래프를 사용하여 dfs를 수행하고 모든 정점들을 같은 SCC로 묶는다.

[ JAVA ]

class Main {
    static ArrayList<Integer> graph[];
    static ArrayList<Integer> reverse[];
    static boolean visited[];
    static Stack<Integer> st = new Stack<>();
    // Result
    static ArrayList<ArrayList<Integer>> a = new ArrayList<>();

    static void dfs(int now) {
        for (int a : graph[now]) {
            if (visited[a] == false) {
                visited[a] = true;
                dfs(a);
            }
        }
        st.push(now);
    }

    static void rdfs(int base, ArrayList<Integer> temp) {
        temp.add(base);
        for (int a : reverse[base]) {
            if (!visited[a]) {
                visited[a] = true;
                rdfs(a, temp);
            }
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer stk = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(stk.nextToken());
        int m = Integer.parseInt(stk.nextToken());

        graph = new ArrayList[n + 1];
        reverse = new ArrayList[n + 1];
        visited = new boolean[n + 1];

        for (int i = 1; i <= n; i++) {
            graph[i] = new ArrayList<>();
            reverse[i] = new ArrayList<>();
        }

        for (int i = 0; i < m; i++) {
            stk = new StringTokenizer(br.readLine());
            int from = Integer.parseInt(stk.nextToken());
            int to = Integer.parseInt(stk.nextToken());
            graph[from].add(to);
            reverse[to].add(from);
        }

        // stack
        for (int i = 1; i <= n; i++) {
            if (!visited[i]) {
                visited[i] = true;
                dfs(i);
            }
        }

        Arrays.fill(visited, false);

        while (!st.isEmpty()) {
            int base = st.pop();
            if (!visited[base]) {
                visited[base] = true;
                ArrayList<Integer> temp = new ArrayList<>();
                rdfs(base, temp);
                Collections.sort(temp);
                temp.add(-1);
                a.add(temp);
            }
        }

        Collections.sort(a, new Comparator<ArrayList<Integer>>() {
            @Override
            public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
                return Integer.compare(o1.get(0), o2.get(0));
            }
        });

        StringBuilder sb = new StringBuilder();
        sb.append(a.size()).append("\n");
        for (int i = 0; i < a.size(); i++) {
            int size = a.get(i).size();
            for (int j = 0; j < size; j++) {
                sb.append(a.get(i).get(j)).append(" ");
            }
            sb.append("\n");
        }
        System.out.println(sb);

        br.close();
    }
}

 

[ C++ ]

#include <stdio.h>
#include <memory.h>
#include <algorithm>
#include <vector>
using namespace std;

typedef vector<int> vi;
const int v_ = 1e4 + 1;

int v, e, cnt, pos, stk[v_];
bool vst[v_];
vi gp1[v_], gp2[v_];
vector<vi> res;

void dfs(int now)
{
    vst[now] = true;
    for (int nxt : gp1[now])
        if (!vst[nxt])
            dfs(nxt);
    stk[pos++] = now;
}

void scc(int now)
{
    vst[now] = true;
    res[cnt].push_back(now);
    for (int nxt : gp2[now])
        if (!vst[nxt])
            scc(nxt);
}

int main()
{
    int i;
    scanf("%d %d", &v, &e);
    for (i = 1; i <= e; i++)
    {
        int a, b;
        scanf("%d %d", &a, &b);
        gp1[a].push_back(b);
        gp2[b].push_back(a);
    }

    for (i = 1; i <= v; i++)
        if (!vst[i])
            dfs(i);

    memset(vst, 0, sizeof(vst));
    while (pos)
    {
        int top = stk[--pos];
        if (vst[top])
            continue;
        res.push_back(vi());
        scc(top);
        cnt++;
    }

    for (i = 0; i < cnt; i++)
        sort(res[i].begin(), res[i].end());
    sort(res.begin(), res.end(), [](const vi &i, const vi &j) { return i[0] < j[0]; });

    printf("%d\n", res.size());

    for (auto &i : res)
    {
        for (auto j : i)
            printf("%d ", j);
        puts("-1");
    }
    return 0;
}
 

 

https://jason9319.tistory.com/98

 

SCC(Strongly Connected Component)

방향 그래프에서 어떤 그룹 X에 있는 임의의 두 정점 A,B에 대해서 항상 A->B로 가는 경로가 존재한다면 그 그룹을 SCC(Strongly Connected Component)라 칭합니다. 더 정확하게 정의하자면 SCC가 되는 그룹은 항..

jason9319.tistory.com

메뉴(파일) - 기본 설정 - 설정 - Font Family

가장 왼쪽부터 폰트가 설정되고, 적용되지 않는 폰트가 있으면 오른쪽으로 적용

 

'이것저것' 카테고리의 다른 글

[VSCODE] Terminal 실행  (0) 2020.05.02
vscode c++ 코드스타일 바꾸기  (0) 2019.05.22
알고리즘 c++ 하는방법  (0) 2019.05.17
[VSCODE] C++ 환경 구축  (0) 2019.05.17
[VSCODE] Power Mode  (0) 2019.05.13

이어지는 간선들을 하나의 집합으로 분류하고 서로소 집합들을 만드는 알고리즘이다. 

Disjoint Set이라고도 부른다.

 

핵심 함수

  • find 함수 : 노드들의 부모를 찾는 과정, 어떤 집합에 포함되있는지 찾는다.
  • union 함수 : 두 노드를 하나의 집합으로 묶는다.

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

 

1717번: 집합의 표현

첫째 줄에 n(1≤n≤1,000,000), m(1≤m≤100,000)이 주어진다. m은 입력으로 주어지는 연산의 개수이다. 다음 m개의 줄에는 각각의 연산이 주어진다. 합집합은 0 a b의 형태로 입력이 주어진다. 이는 a가 포함되어 있는 집합과, b가 포함되어 있는 집합을 합친다는 의미이다. 두 원소가 같은 집합에 포함되어 있는지를 확인하는 연산은 1 a b의 형태로 입력이 주어진다. 이는 a와 b가 같은 집합에 포함되어 있는지를 확인하는 연산이다. a

www.acmicpc.net

 
public class Main {
    static int n, m, parent[];
 
    static int find(int x) {
        if (parent[x] == x)
            return x;
        return parent[x] = find(parent[x]);
    }
 
    static void union(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y)
            return;
        parent[y] = x;
    }
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
 
        parent = new int[n + 1];
 
        for (int i = 0; i <= n; i++)
            parent[i] = i;
 
        StringBuilder sb = new StringBuilder();
        for (int i = 0, t, x, y; i < m; i++) {
            st = new StringTokenizer(br.readLine());
            t = Integer.parseInt(st.nextToken());
            x = Integer.parseInt(st.nextToken());
            y = Integer.parseInt(st.nextToken());
            if (t == 0) {
                union(x, y);
            } else {
                sb.append(find(x) == find(y) ? "YES" : "NO").append("\n");
            }
        }
 
        System.out.println(sb);
 
        br.close();
    }
}
 

간과했던 부분 ( line : 38 )

두 노드가 같은 집합인지 확인할 때, find 함수를 통해 찾는다면 재귀를 다시 사용해야 했기 떄문에 불필요하다고 생각했고, parent 배열을 확인하여 O(1) 만에 같은 집합인지 알 수 있을 것이라고 생각했다. 

3 3
0 2 3
0 1 2
1 1 3

하지만 이러한 반례의 경우, 3의 부모는 2가 될 것이고, 2의 부모는 1이 될 것이다. 노드 1, 2, 3은 같은 집합이지만 1과 3노드가 같은 집합인지 확인할 경우 parent 배열에 다른 값이 들어 가있는 상태이고, 같은 집합임에 불구하고 NO를 출력했던 것이다. 따라서 같은 집합인지 확인하기 전 find를 호출하여 다시 루트노드까지 가는 과정을 통해 parent 배열을 최신화해주는 것을 통해 해결할 수 있었다.

'알고리즘 ' 카테고리의 다른 글

백준 1941 : 소문난 칠공주  (0) 2019.05.21
SCC - kosaraju  (0) 2019.05.21
Parametric search (파라메트릭 서치)  (0) 2019.05.16
[JAVA] KMP 알고리즘(문자열 검색)  (0) 2019.05.13
백준 1253 : 좋다  (0) 2019.04.19
입출력
#include <bits/c++io.h>
#include <stdio.h>
#include <cstdio>
int n;
int main() {
    scanf("%d",&n);
    printf("hello C++! %d",n);
}
#include <iostream>
using namespace std;
int n;
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(nullptr);
    cin >> n;
    cout << "hello C++! " << n;
}

endl  ,  \n  

endl은 출력 후 버퍼를 비우는 역할을 수행하기 때문에 많이 느리다.

 

using namespace std 에 대해서

 

배열 미리 최대범위까지 선언하는것과  배열 범위 입력받고 선언하는법

 

string 사용법 

 

 

'이것저것' 카테고리의 다른 글

[VSCODE] Terminal 실행  (0) 2020.05.02
vscode c++ 코드스타일 바꾸기  (0) 2019.05.22
[VSCODE] 글씨 폰트 설정  (0) 2019.05.18
[VSCODE] C++ 환경 구축  (0) 2019.05.17
[VSCODE] Power Mode  (0) 2019.05.13

https://webnautes.tistory.com/1158

 

Visual Studio Code에서 C/C++ 프로그래밍( Windows / Ubuntu)

Windows와 Ubuntu 환경에 설치된 Visual Studio Code에서 C/C++을 컴파일하고 실행시키는 방법에 대해 설명합니다. 테스트에 사용한 운영체제 버전은 Windows 10과 Ubuntu 18.04입니다. 1. C/C++ 컴파일러 설치 2...

webnautes.tistory.com

 

'이것저것' 카테고리의 다른 글

[VSCODE] Terminal 실행  (0) 2020.05.02
vscode c++ 코드스타일 바꾸기  (0) 2019.05.22
[VSCODE] 글씨 폰트 설정  (0) 2019.05.18
알고리즘 c++ 하는방법  (0) 2019.05.17
[VSCODE] Power Mode  (0) 2019.05.13

+ Recent posts