MST 알고리즘
비용을 절약하는 값은 모든 인접 비용의 총합에서 - 최소 스패닝 트리의 값을 뺀 값이다.
크루스칼
union()
을 통해 대표값이 업데이트 되는 구간이 최소 스패닝 트리에 포함되는 의 값이다. 대표값을 찾은 후, 이를 비교하여 만약 서로 다르다면 이때 값을 모든 인접비용의 총합에서 빼주자.프림
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
typedef pair<int, int> pi;
int m, n, sumDist;
const int M_MAX = 200004;
vector<pi> v[M_MAX];
bool visited[M_MAX];
struct cmp {
bool operator()(pi p1, pi p2) {
return p1.second > p2.second;
}
};
void prim() {
priority_queue<pi, vector<pi>, cmp> pq;
visited[0] = true;
for (int i = 0; i < v[0].size(); i++) pq.push(v[0][i]);
while (!pq.empty()) {
pi curr = pq.top();
pq.pop();
if (visited[curr.first]) continue;
visited[curr.first] = true;
sumDist -= curr.second;
for (auto next: v[curr.first]) {
if(visited[next.first]) continue;
pq.push({next.first, next.second});
}
}
}
void output() {
cout << sumDist<< "\n";
}
void input() {
while (1) {
cin >> m >> n;
if (m == 0 && n == 0) break;
for (int i = 0; i < m; i++) v[i].clear();
sumDist = 0;
int s, e, dist;
for(int i=0; i<n; i++) {
cin >> s >> e >> dist;
v[s].push_back({e, dist});
v[e].push_back({s, dist});
sumDist += dist;
}
memset(visited, 0, sizeof(visited));
prim();
output();
}
}
int main() {
input();
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer stk;
static int m, n, p[], result;
static PriorityQueue<int[]> pq;
private static int getFind(int n) {
if(n == p[n]) return n;
else return p[n] = getFind(p[n]);
}
private static boolean setUnion(int x, int y) {
int fx = getFind(x);
int fy = getFind(y);
if(fx == fy) return false;
p[fx] = fy;
return true;
}
private static void kruskal() {
while(!pq.isEmpty()) {
int[] curr = pq.poll();
if(setUnion(curr[0], curr[1])) result -= curr[2];
}
}
private static void input2() throws Exception {
while (true) {
stk = new StringTokenizer(br.readLine());
m = Integer.parseInt(stk.nextToken());
n = Integer.parseInt(stk.nextToken());
if (m == 0 && n == 0) return;
p = new int[m];
for (int i = 0; i < m; i++) p[i] = i;
result = 0;
pq = new PriorityQueue<>((n1, n2) -> n1[2] - n2[2]);
for (int i = 0; i < n; i++) {
stk = new StringTokenizer(br.readLine());
int[] curr =new int[]{Integer.parseInt(stk.nextToken()), Integer.parseInt(stk.nextToken()), Integer.parseInt(stk.nextToken())};
pq.add(curr);
result += curr[2];
}
kruskal();
System.out.println(result);
}
}
public static void main(String[] args) throws Exception {
input2();
}
}