문제

1197번 문제 링크

1922번 문제 링크

어떻게 접근할 것인가

  • 그동안 알고 있던 유니온 파인드를 이용해서 풀었다.
  • 근데 사이클체크를 더 효율적으로 하면서 진행하는 코드가 있어서 그것을 공유하고자 한다.

코드

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#define X first
#define Y second
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using T = pair<int, pii>;

int pa[10000];

char buf[1 << 17];

inline char read() {
    static int idx = 1 << 17;
    if (idx == 1 << 17) {
        fread(buf, 1, 1 << 17, stdin);
        idx = 0;
    }
    return buf[idx++];
}
inline int readInt() {
    int sum = 0;
    bool flg = 1;
    char now = read();

    while (now == 10 || now == 32) now = read();
    if (now == '-') flg = 0, now = read();
    while (now >= 48 && now <= 57) {
        sum = sum * 10 + now - 48;
        now = read();
    }

    return flg ? sum : -sum;
}

int fnd(int n) {
    if (!pa[n]) return n;
    return pa[n] = fnd(pa[n]);
}

void uni(int a, int b) {
    a = fnd(a);
    b = fnd(b);
    pa[b] = a;
}

int main() {
    int v = readInt(), e = readInt();

    int a, b, c;
    vector<T> edge;
    for (int i = 0; i < e; ++i) {
        a = readInt();
        b = readInt();
        c = readInt();
        edge.push_back({ c, { a, b } });
    }

    sort(edge.begin(), edge.end());

    int ans = 0;
    for (T &it : edge) {
        if (fnd(it.Y.X) == fnd(it.Y.Y)) continue;
        ans += it.X;
        uni(it.Y.X, it.Y.Y);
    }

    printf("%d", ans);

    return 0;
}
  • 이 코드는 YunGoon님의 코드이다.
  • 일단 어차피 weight 순으로 sorting 해야하기 때문에 vector의 pair를 이용해서 첫번째 값을 weight로 놓으셨다.
  • 그리고 cycle_check를 위해 find로 같은지 매번 비교해줬다.
  • 합쳐주고 ans를 올려주고가 끝인데 알고리즘 속도가 엄청 빨라졌다.
  • 나는 유니온 파인드 강화 알고리즘을 이용해봤는데 그것 안쓰고도 지금 충분히 빨랐다!!

느낀점

  • 굳이 isCycle이라는 함수 필요없이 find만 비교하면 되는데 참 대단하다 이렇게 단순하게 코드를 짤 수 있고 시간도 아낄 수 있다는건 참 좋은 것 같다.
  • 여기에 유니온 파인드 강화도 쓰면 좋을 것 같은데 일단 시간이 안줄기 때문에 패쓰하자!