πŸ™‡β€β™€οΈ[Platinum V] ν–‰μ„± 터널 - 2887

문제 링크

μ„±λŠ₯ μš”μ•½

λ©”λͺ¨λ¦¬: 15660 KB, μ‹œκ°„: 96 ms

λΆ„λ₯˜

κ·Έλž˜ν”„ 이둠, μ΅œμ†Œ μŠ€νŒ¨λ‹ 트리, μ •λ ¬

제좜 일자

2024λ…„ 3μ›” 6일 13:42:12

문제 μ„€λͺ…

λ•ŒλŠ” 2040λ…„, μ΄λ―Όν˜μ€ μš°μ£Όμ— μžμ‹ λ§Œμ˜ 왕ꡭ을 λ§Œλ“€μ—ˆλ‹€. 왕ꡭ은 N개의 ν–‰μ„±μœΌλ‘œ 이루어져 μžˆλ‹€. λ―Όν˜μ΄λŠ” 이 행성을 효율적으둜 μ§€λ°°ν•˜κΈ° μœ„ν•΄μ„œ 행성을 μ—°κ²°ν•˜λŠ” 터널을 λ§Œλ“€λ €κ³  ν•œλ‹€.

행성은 3차원 μ’Œν‘œμœ„μ˜ ν•œ 점으둜 μƒκ°ν•˜λ©΄ λœλ‹€. 두 ν–‰μ„± A(xA, yA, zA)와 B(xB, yB, zB)λ₯Ό ν„°λ„λ‘œ μ—°κ²°ν•  λ•Œ λ“œλŠ” λΉ„μš©μ€ min(|xA-xB|, |yA-yB|, |zA-zB|)이닀.

λ―Όν˜μ΄λŠ” 터널을 총 N-1개 κ±΄μ„€ν•΄μ„œ λͺ¨λ“  행성이 μ„œλ‘œ μ—°κ²°λ˜κ²Œ ν•˜λ €κ³  ν•œλ‹€. μ΄λ•Œ, λͺ¨λ“  행성을 ν„°λ„λ‘œ μ—°κ²°ν•˜λŠ”λ° ν•„μš”ν•œ μ΅œμ†Œ λΉ„μš©μ„ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 ν–‰μ„±μ˜ 개수 N이 주어진닀. (1 ≀ N ≀ 100,000) λ‹€μŒ N개 μ€„μ—λŠ” 각 ν–‰μ„±μ˜ x, y, zμ’Œν‘œκ°€ 주어진닀. μ’Œν‘œλŠ” -109보닀 ν¬κ±°λ‚˜ κ°™κ³ , 109보닀 μž‘κ±°λ‚˜ 같은 μ •μˆ˜μ΄λ‹€. ν•œ μœ„μΉ˜μ— 행성이 두 개 이상 μžˆλŠ” κ²½μš°λŠ” μ—†λ‹€.

좜λ ₯

첫째 쀄에 λͺ¨λ“  행성을 ν„°λ„λ‘œ μ—°κ²°ν•˜λŠ”λ° ν•„μš”ν•œ μ΅œμ†Œ λΉ„μš©μ„ 좜λ ₯ν•œλ‹€.

πŸš€ν’€μ΄

kruskalμ•Œκ³ λ¦¬μ¦˜μ„ μ΄μš©ν•΄μ„œ 문제λ₯Ό ν’€λ €κ³ ν–ˆλ‹€.

각 μ •μ μ˜ λΉ„μš©λ“€μ„ λΉ„κ΅ν•˜λ©΄μ„œ ν’€λ €κ³  ν–ˆλŠ”λ° μ΅œλŒ€ 정점이 10λ§Œκ°œμ—¬μ„œ λͺ¨λ“  정점을 μ΄μ„μ‹œμ— λ©”λͺ¨λ¦¬ μ΄ˆκ³Όκ°€ 났닀.

문제의 핡심은 λͺ¨λ“  μ •μ μ˜ 거리λ₯Ό λΉ„κ΅ν•˜μ§€ 말고 κ·Όμ²˜μ— μžˆλŠ” μ •μ λ“€λ§Œ 비ꡐλ₯Ό ν•΄μ„œ μ—°κ²° 정보λ₯Ό λ„£μ–΄μ€˜μ•Όν–ˆλ‹€.

πŸš€μ „μ²΄ μ½”λ“œ

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include<iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <math.h>

using namespace std;

// ν–‰μ„± 터널
// kruskal 문제

struct Edge
{
	int cost;
	int u, v;
	bool operator<(Edge& other)
	{
		return cost < other.cost;
	}
};

const int MAX = 111111;
int unf[MAX];
int n;
vector<pair<int, int>> v[3];
vector<Edge> planet;

int Find(int u)
{
	if (u == unf[u])
		return u;
	return unf[u] = Find(unf[u]);
}

void Merge(int u, int v)
{
	u = Find(u);
	v = Find(v);

	if (u == v)
		return;

	unf[u] = v;
}

void solve()
{
	cin >> n;
	int x, y, z;

	for (int i = 0; i < n; ++i)
	{
		cin >> x >> y >> z;
		v[0].push_back({ x, i });
		v[1].push_back({ y, i });
		v[2].push_back({ z, i });
		unf[i] = i;
	}

	sort(v[0].begin(), v[0].end());
	sort(v[1].begin(), v[1].end());
	sort(v[2].begin(), v[2].end());

	for (int i = 0; i < n - 1; ++i)
	{
		planet.push_back({ abs(v[0][i].first - v[0][i + 1].first), v[0][i].second, v[0][i + 1].second});
		planet.push_back({ abs(v[1][i].first - v[1][i + 1].first), v[1][i].second, v[1][i + 1].second});
		planet.push_back({ abs(v[2][i].first - v[2][i + 1].first), v[2][i].second, v[2][i + 1].second});
	}

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

	int ret = 0;
	for (int i = 0; i < planet.size(); ++i)
	{
		if (Find(planet[i].u) == Find(planet[i].v))
			continue;

		ret += planet[i].cost;
		Merge(planet[i].u, planet[i].v);
	}

	cout << ret;
}

int main() 
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	freopen("input.txt", "rt", stdin);

	solve();

	return 0;
}

νƒœκ·Έ:

μΉ΄ν…Œκ³ λ¦¬:

μ—…λ°μ΄νŠΈ: