๊ตฌ๋ฆ„ํ†ค ์ฑŒ๋ฆฐ์ง€ 4์ฃผ ์ฐจ ํ•™์Šต ์ผ๊ธฐ - 2
ย - Last update: 2023-09-05

๊ตฌ๋ฆ„ํ†ค ์ฑŒ๋ฆฐ์ง€๋ž€?

๊ตฌ๋ฆ„ ์ด๋ผ๋Š” ๊ณณ์—์„œ ๋ฌธ์ œ ํ’€์ด ์ฑŒ๋ฆฐ์ง€(๊ตฌ๋ฆ„ํ†ค ์ฑŒ๋ฆฐ์ง€)๋ฅผ ํ•œ๋‹ค๊ณ  ํ•ด์„œ ์ฐธ์—ฌ ์ค‘์ด๋‹ค. ์ด๋ฒคํŠธ ๊ธฐ๊ฐ„ ๋™์•ˆ ๋ฌธ์ œ๊ฐ€ ๊พธ์ค€์ด ์˜ฌ๋ผ์˜ค๋ฉฐ, ์ฃผ์— 2ํšŒ์”ฉ (ํ˜น์€ ๊ทธ ์ด์ƒ) ์ฑŒ๋ฆฐ์ง€ ๋ฌธ์ œ๋“ค์— ๋Œ€ํ•ด ํ’€์ด๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ฌธ์ œ๋“ค์„ ํ’€์ดํ•ด๋ณด๊ณ , ํ›„๊ธฐ๋ฅผ ๋‚จ๊ฒจ๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

๋ฌธ์ œ ํ’€์ด

ํ’€์ด ์ ‘๊ทผ

์–ด์ œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‚˜์˜ ๊ฒฝ์šฐ Union Find๋กœ ์ ‘๊ทผํ–ˆ๋‹ค. ๊ฐ™์€ ์ง‘ํ•ฉ์— ์†ํ•˜๋Š” ๋…€์„๋“ค์„ ๊ด€๋ฆฌํ•  ๋•Œ๋Š” ์ด ๋ฐฉ๋ฒ•์ด ์ œ์ผ ํŽธํ•˜๋‹ค.

ํ’€์ด ๊ณผ์ •์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  1. ์ž…๋ ฅ์„ ๋ฐ›์œผ๋ฉด์„œ ๊ฐ™์€ ์ง‘ํ•ฉ์— ์†ํ•˜๋Š” ์• ๋“ค์„ merge ํ•œ๋‹ค
  2. ๋‹ค์‹œ ์ฒ˜์Œ๋ถ€ํ„ฐ ์ •์ ์„ ์ˆœํšŒํ•˜๋ฉด์„œ root๋ฅผ ํ™•์ธํ•ด์„œ, ์ฒ˜์Œ ๋‚˜์˜ค๋Š” root ๋ฉด Component๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
    • ํ˜„์žฌ ์ •์ ์ด ์†ํ•œ Component์— ํ•ด๋‹น ์ปดํ“จํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
  3. Component ์•ˆ์— ์†ํ•˜๋Š” ์ปดํ“จํ„ฐ๋“ค์ด ๊ฐ€์ง„ ๊ฐ„์„ ์˜ ๊ฐฏ์ˆ˜๋ฅผ ์„ธ์„œ ๋ฐ˜์˜ํ•œ๋‹ค.
  4. ๋ฌธ์ œ์—์„œ ์ค€ ๊ธฐ์ค€์œผ๋กœ Component๋ฅผ ์ •๋ ฌํ•œ๋‹ค.
  5. 0๋ฒˆ์งธ index์˜ Component์˜ ์›์†Œ๋“ค์„ ์ถœ๋ ฅํ•œ๋‹ค.

๊ทธ๋ž˜ํ”„๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฒ•๋งŒ ์ž˜ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด ์ˆœ์ˆ˜ ๊ตฌํ˜„ ๋ฌธ์ œ์ฒ˜๋Ÿผ ํ’€์ด๊ฐ€ ๋œ๋‹ค.

์ฃผ์˜ํ•ด์•ผํ•  ์ ์€ ์ •๋ ฌํ•  ๋•Œ ์ธ๋ฐ, ๋ฐ€๋„์˜ ๊ณ„์‚ฐ์„ ๋ถ„์ˆ˜๋กœ ํ•˜๊ฒŒ ๋˜๋ฉด WA๋ฅผ ๋ฐ›๊ธฐ ์‰ฝ๋‹ค. ์ด ๊ฒฝ์šฐ ๋ถ„์ˆ˜๋กœ ํ•˜๊ธฐ๋ณด๋‹ค๋Š” a/ba / b์™€ c/dc / d๋ฅผ ๋น„๊ตํ•œ๋‹ค ํ•  ๋•Œ aโˆ—da * d์™€ bโˆ—cb * c๋ฅผ ๋น„๊ตํ•˜๋Š” ์‹์œผ๋กœ ํšŒํ”ผํ•˜๋ฉด ์‹ค์ˆ˜ ์˜ค์ฐจ ์—†์ด ์ •๋ ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜, ์ด ๊ฒฝ์šฐ ๋ฌธ์ œ ์กฐ๊ฑด์—์„œ ์ˆ˜์˜ ๋ฒ”์œ„๊ฐ€ int ๋ฒ”์œ„๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, long long์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. (Worst ์‹œ 105ร—2โˆ—105=2โˆ—101010^5 \times 2*10^5 = 2*10^{10} > 0x7FFFFFFF ์ด๋‹ค)

์‹œ๊ฐ„ ๋ณต์žก๋„์˜ ๋ณ‘๋ชฉ ๋ถ€๋ถ„์€ ์ •๋ ฌ๊ณผ ์ฒ˜์Œ ๊ฐ„์„  ์ž…๋ ฅ์„ ๋ฐ›๋Š” ๋ถ€๋ถ„์ด๊ณ , O(M+NlogโกN)O(M + N \log N)์ด๋‹ค.

๋‚ด ํ’€์ด

#include <bits/stdc++.h>
using namespace std;
int N, M;
typedef long long ll;
struct UF {
int parent[100001];
UF() {
for(int i = 0; i <= 100000; ++i) parent[i] = i;
}
int getRoot(int v) {
if (v == parent[v]) return v;
return parent[v] = getRoot(parent[v]);
}
void merge(int a, int b) {
a = getRoot(a);
b = getRoot(b);
if (a == b) return;
parent[b] = a;
}
} uf;
vector<int> adj[100001];
struct Component {
ll numComputer;
ll numConnection;
vector<int> members;
bool operator<(const Component& t) const {
// 1. ์ปค๋„ฅ์…˜ ์ˆ˜ / ์ปดํ“จํ„ฐ ์ˆ˜
// 2. ๋ฐ€๋„ ๊ฐ™์œผ๋ฉด ์ปดํ“จํ„ฐ ์ ์€ ์ˆ˜
// 3. ๋” ์ž‘์€ ๋ฒˆํ˜ธ ์ปดํ“จํ„ฐ ์ˆœ
if (numComputer * t.numConnection != numConnection * t.numComputer) {
return numComputer * t.numConnection < numConnection * t.numComputer;
}
if (numComputer != t.numComputer) {
return numComputer < t.numComputer;
}
return members[0] < t.members[0];
}
} com[100000];
int main() {
scanf("%d %d", &N, &M);
for(int i = 0; i < M; ++i) {
int a, b; scanf("%d %d", &a, &b);
adj[a].push_back(b);
uf.merge(a, b);
}
int cid = 0;
map<int, int> uq;
for(int a = 1; a <= N; ++a) {
if (uq.find(uf.getRoot(a)) == uq.end()) {
uq[uf.getRoot(a)] = cid;
++cid;
}
int gid = uq[uf.getRoot(a)];
com[gid].members.push_back(a);
com[gid].numComputer++;
}
for(int c = 0; c < cid; ++c) {
ll cnt = 0;
for(auto& cur: com[c].members) {
cnt += adj[cur].size();
}
com[c].numConnection = cnt;
}
sort(com, com + cid);
for(auto& item: com[0].members) {
printf("%d ", item);
}
printf("\n");
return 0;
}
๐Ÿท๏ธ ์ฃผ์ œ ๋ชฉ๋ก: