https://www.acmicpc.net/problem/1197
MST 기본문제.
Unionfind
findRoot 할때 메모이제이션하는것 잊지말자.
현재 노드에서 재귀적으로 갈 수 잇는 최대 root를 바로 vRoot에 저장하면
속도를 훨씬 줄일 수 있다.
Kruskal은 항상 작은 비용이 드는 간선부터 확인해보되
간선이 연결하고 있는 두 노드 i 와 j 가 이미 연결되어있나 확인하고
연결이 안되어있을때 연결시켜준다.
연결여부 확인은 서로의 루트노드를 재귀적으로 따라가서 그 결과
루트노드가 같은지 여부를 확인하는 것이다.
연결해주는 것은 서로의 루트노드에 상하관계를 만들어주는 것이다.
j 의 최상단 루트의 루트를 i 의 최상단루트로 처리한다.
따라서 현재 i 와 j 를 포함한 모든 노드들의 최상단 루트는 i 의 최상단루트로 통일된다.
또한 처음에 속도가 100ms가 나왔는데 다른 분들은 c++ 기준 100ms 이하로 풀었길래
어디서 속도를 줄일 수 있을 지 고민해보았다.
일단 가장 확실한 방법은 무조건
ios_base::sync_with_stdio(false);
cin.tie(0);
을 쓰고 시작하는 것이다. 이 두 줄 추가했더니 36ms가 되었다.
단 이때는 cin, cout 과 printf, scanf 를 혼용해서 사용하면 안된다.(무조건 cin, cout만)
printf 와 scanf 를 사용 하는 것이 제일 무난하지만 cout 과 cin 에 익숙해서..
위에 두 줄 추가하면 printf, scanf와 비슷한 성능을 낼 수 있다.
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 | #include <iostream> #include <vector> #include <algorithm> #include <cstring> using namespace std; int v, e; class Edge{ public: int i = 0; int j = 0; int weight = 0; bool operator<(const Edge &v) const{ return weight < v.weight; } Edge(int i = 0, int j = 0, int weight = 0) :i(i), j(j), weight(weight) {} }; int vRoot[10001] = {0, }; vector<Edge> edges; int cost = 0; int findRoot(int v){ if(vRoot[v] == v){ return v; } return vRoot[v] = findRoot(vRoot[v]); } void kruskal(){ //sort부터 한다 weight 오름차순으로 //각 노드의 루트를 정의해준다 sort(edges.begin(), edges.end()); for(Edge it : edges){ //현재 간선을 놓을때 cycle이 발생하나 여부 확인 //-> 노드 i 와 노드 j 의 각 뿌리가 같으면 cycle 발생(이미 연결되어있다) //-> 각 뿌리가 다르면 연결해도 됨. int rootI = findRoot(it.i); int rootJ = findRoot(it.j); if(rootI != rootJ){ //union find 연결. //서로의 뿌리끼리 연결해준다. vRoot[rootJ] = rootI; cost += it.weight; } } } int main(){ ios_base::sync_with_stdio(false); cin.tie(0); cin >> v >> e; for(int i = 1; i <= v; i++){ vRoot[i] = i; } while(e--){ int i, j, w; cin >> i >> j >> w; edges.push_back(Edge(i, j, w)); } kruskal(); cout << cost << endl; return 0; } |
'BOJ 문제풀이 > 최소스패닝트리 (MST)' 카테고리의 다른 글
백준 1774 : 우주신과의 교감 (0) | 2018.11.30 |
---|---|
백준 2463 : 비용 (0) | 2018.11.30 |
백준 4386 : 별자리 만들기 (0) | 2018.11.29 |
백준 13418 : 학교 탐방하기 (0) | 2018.11.29 |
백준 16398 : 행성 연결 (0) | 2018.11.29 |