·593 words·3 mins
๐ ๋ฌธ์ ์ ๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/24452 ๋ฒ์ญ ๋ฌธ์ ๋ฒ์ญ # JOI ์ฐ๋ฐฉ๊ตญ์๋ 1๋ถํฐ N๊น์ง ๋ฒํธ๊ฐ ๋งค๊ฒจ์ง N๊ฐ์ ๋์์, 1๋ถํฐ M๊น์ง ๋ฒํธ๊ฐ ๋งค๊ฒจ์ง M๊ฐ์ ๋๋ก๊ฐ ์๋ค. ๋๋ก i (1 โฆ i โฆ M)๋ ๋์ Ui์ ๋์ Vi๋ฅผ ์๋ฐฉํฅ์ผ๋ก ์ฐ๊ฒฐํ๊ณ ์๋ค.
JOI ์ฐ๋ฐฉ๊ตญ์ 1๋ถํฐ K๊น์ง ๋ฒํธ๊ฐ ๋งค๊ฒจ์ง K๊ฐ์ ์ฃผ(ๅท)๋ก ์ด๋ฃจ์ด์ ธ ์๋ค. ๋์ j (1 โฆ j โฆ N)๋ ์ฃผ Sj์ ์ํด ์๋ค. ๋ํ, ๋ชจ๋ ์ฃผ๋ ์ ์ด๋ ํ๋์ ๋์๋ฅผ ํฌํจํ๋ค.
·57 words·1 min
๐ ๋ฌธ์ ์ ๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/31055 ๋ฒ์ญ ๋ฌธ์ ๋ฒ์ญ # Bessie๋ ์ํ ์ง์์ ํฅ์์ํค๊ธฐ ์ํด ๊ทธ๋ํ ์ด๋ก ๊ฐ์ข๋ฅผ ์๊ฐํ๊ณ ์๋๋ฐ, ๋ค์ ๋ฌธ์ ์์ ๋งํ์ต๋๋ค. ๊ทธ๋
๋ฅผ ๋์์ฃผ์ธ์!
์ฐ๊ฒฐ๋ ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ๊ฐ ์ฃผ์ด์ง๋๋ค. ์ ์ ์ $1\dots N$์ผ๋ก, ๊ฐ์ ์ $1\dots M$์ผ๋ก ๋ผ๋ฒจ๋ง๋์ด ์์ต๋๋ค ($2\le N\le 2\cdot 10^5$, $N-1\le M\le 4\cdot 10^5$).
๊ทธ๋ํ์ ๊ฐ ์ ์ $v$์ ๋ํด ๋ค์ ๊ณผ์ ์ ์ํํฉ๋๋ค:
·176 words·1 min
๐ ๋ฌธ์ ์ ๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/3830 ๐ง ๊ด์ฐฐ ๋ฐ ์ ๊ทผ # ๋ ๊ฐ์ ์ฐจ์ด๋ฅผ ํธ๋ฆฌ ํํ๋ก ์ ์ฅํ๋ค๊ณ ์๊ฐํ์. ๊ฐ์ ์ ๊ฐ์ค์น๊ฐ ์๋ ํธ๋ฆฌ๊ฐ ๋ ๊ฒ์ด๋ค. ๋ ๊ฐ $a, b$๊ฐ ๊ฐ์ ํธ๋ฆฌ์ ์๋ค๋ฉด ๋น๊ต ๊ฐ๋ฅํ๊ณ , ๊ทธ๋ ์ง ์๋ค๋ฉด ๋น๊ต ๋ถ๊ฐ๋ฅํ๋ค. ํ์ง๋ง ์ด ๊ฒฝ์ฐ ํธ๋ฆฌ๊ฐ ์ง์ ํ์ด ๋๋ฉด, ์ต์
์ ๊ฒฝ์ฐ $O(N)$์ด ๊ฑธ๋ฆฐ๋ค. ์ฐ๋ฆฌ๋ ์ด๋ฌํ ๊ฒฝ์ฐ์ UnionFind์์ ๊ฒฝ๋ก ์์ถ์ ํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ๋ค. ๊ฒฐ๊ตญ ๋ฃจํธ๊น์ง์ ๊ฐ์ ๊ฐ์ค์น ํฉ์ ์ ์ฅํด์ ์ด์ฉํ๋ฉด ๋๋ค. ๐ป ํ์ด # ์ฝ๋ (C++): void solve(){ while(1){ int N, M; cin >> N >> M; if(N + M == 0) break; UnionFind uf(N); while(M--){ char op; cin >> op; if(op == '!'){ int a, b, w; cin >> a >> b >> w; uf.merge(a-1, b-1, w); } else{ int a, b; cin >> a >> b; auto [ra, wa] = uf.find(a-1); auto [rb, wb] = uf.find(b-1); if(ra != rb) cout << "UNKNOWN\n"; else cout << wb - wa << '\n'; } } } } ๐ ๊ตฌํ ์ฝ๋ ์ ๊ธ
·512 words·3 mins
๐ ๋ฌธ์ ์ ๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/21932 ๋ฒ์ญ ๋ฌธ์ ๋ฒ์ญ # ๋ฌธ์ ์ค๋ช
# ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ๊ฐ ์ฃผ์ด์ง๊ณ , ๊ฐ ๋
ธ๋์๋ ์์ ์ ์ ๊ฐ์ด ์ฐ๊ฒฐ๋์ด ์์ต๋๋ค. ์๊ณ๊ฐ(threshold)์ด ์ฃผ์ด์ง๋ฉด, ๊ทธ๋ํ์ ๋
ธ๋๋ค์ ๋ ๊ทธ๋ฃน์ผ๋ก ๋๋ฉ๋๋ค: ํ๋๋ ์๊ณ๊ฐ ์ดํ์ ๊ฐ์ ๊ฐ์ง ๋
ธ๋๋ค๋ก ๊ตฌ์ฑ๋๊ณ , ๋ค๋ฅธ ํ๋๋ ๋๋จธ์ง ๋
ธ๋๋ค๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. ์ด์ ์๋ก ๋ค๋ฅธ ๊ทธ๋ฃน์ ์ํ ๋ ๋
ธ๋๋ฅผ ์ฐ๊ฒฐํ๋ ๋ชจ๋ ๊ฐ์ ์ ์ ๊ฑฐํ์ฌ ์ป์ ์๋ ๊ทธ๋ํ์ ๋ถ๋ถ ๊ทธ๋ํ๋ฅผ ๊ณ ๋ คํฉ๋๋ค. ๋ ๋
ธ๋ ๊ทธ๋ฃน์ด ๋ชจ๋ ๋น์ด์์ง ์์ ๋, ์ฃผ์ด์ง ๊ทธ๋ํ๊ฐ ์ฐ๊ฒฐ๋์ด ์๋์ง ์ฌ๋ถ์ ๊ด๊ณ์์ด ๊ฒฐ๊ณผ ๋ถ๋ถ ๊ทธ๋ํ๋ ์ฐ๊ฒฐ์ด ๋์ด์ง๋๋ค.
·584 words·3 mins
๐ ๋ฌธ์ ์ ๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/18180 ๋ฒ์ญ ๋ฌธ์ ๋ฒ์ญ # ๋ฐ์ดํน ๋ฝ ์ด๋์๋ ๋ค์ํ ํ๋ฆ์ด ์กด์ฌํ๋ค. ์ฌ๋ ์์ด์ฌ๋๋ ๊ทธ๋๋ํธ ๋ฝ, ๋ฏธ๋ค ๋ฐ๋์ฌ ๋์คํฐ ๋ฐ์ดํน ๋ฝ, ๋ ์ดํธ ํ๊ฒ์ผ ๋คํฌ ๊ทธ๋ฆฐ ๋ฝ, ํผ์ค๋ฅด๋ ๋ณผ๋ ์๋ฐ๋์ฒด ๋ฝ ๋ฑ, ์ธ๊ธฐ ์๋ ํ๋ฆ์ ์ ์ฒด ๋ชฉ๋ก์ ๋์ดํ๋ฉด ์ด ํ์ด์ง๋ฅผ ์ฌ๋ฌ ๋ฒ ๊ฐ๋ ์ฑ์ธ ์ ๋์ด๋ค. ์ค์นธ๋๋๋น์ ๊ณ ๋ฑ๊ต์ก๋ถ๋ ์ด๋ฌํ ํ๋ฆ๋ค์ด ์๋ก ์ด๋ป๊ฒ ์ํฅ์ ์ฃผ๋์ง ์ฐ๊ตฌํ๊ณ ์๋ค. ๊ทธ๋ค์ ํ์ฌ ๋๊ท๋ชจ ์คํ์ ๊ณํ ์ค์ด๋ฉฐ, ์ ์ ํ ์ ๋ฐ๋ ์์๋ด์ฌ์๋ค์ ๋ฌด์ธ๋๋ค๋ก ๊ตฌ์ฑ๋ ๊ตฐ๋์ ๋ฐฐ์นํ์ฌ ์๋์ ์ผ๋ก ๊ธด ์๊ฐ ๋์ ๊ทธ๋ค์ ์์
์ ์คํ์ผ๊ณผ ์ ํธ๋๊ฐ ์๋ก ๋ฏธ์น๋ ์ํฅ์ ๊ด์ฐฐํ๊ณ ์ ํ๋ค.
·332 words·2 mins
๐ ๋ฌธ์ ์ ๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/25567 ๐ง ๊ด์ฐฐ ๋ฐ ์ ๊ทผ # ๊ตฌ๊ฐํฉ?์ ํ๋ ค๋ฉด ๊ฒฐ๊ตญ ์์ฑ๋ ๋ฐฐ์ด์ด ์์ผ๋ฉด ์ข์๊ฑฐ๊ฐ์๋ฐ.. ๊ทผ๋ฐ ์ค์ด ๋ค๋ฅผ๋๋ง ํฉ์น๋๊น, ๊ฒฐ๊ตญ ์์ฑ๋ ์ค์ ๊ณ ์ ์ ์ผ๋ก ์กด์ฌํ๋ค! ์คํ๋ผ์ธ์ผ๋ก ์ ๋๋ฉด์ ์ฒ๋ฆฌํ๋ฉด ๋๋๊ฑฐ๊ฐ๋ค. ์ค์ ๋งจ์๊ณผ ๋งจ๋ค๊ฐ ์ด๋์ง ์ ๊ด๋ฆฌํ๊ณ , ๋ชจ๋ ์ค์ด ํฉ์ณ์ง์ง๋ ์์ ์ ์์ผ๋ ์ด๋ฅผ ์ฃผ์ํ์. ๐ป ํ์ด # ์ฝ๋ (C++): void solve(){ int N; cin >> N; int sz = 0; vector<vector<int>> lines; rep(i, 0, N){ int cnt; cin >> cnt; vector<int> line(cnt); rep(j, 0, cnt) cin >> line[j]; lines.push_back(line); sz += cnt; } vector<array<int, 3>> Queries; // {query, a, b} int Q; cin >> Q; rep(i, 0, Q){ int op, a, b; cin >> op >> a >> b; Queries.push_back({op, a, b}); } // lineId[x] = i : x๋ฒ ์ฌ๋์ด i๋ฒ์งธ ์ค์ ์ํจ vector<int> lineId(sz+1); rep(i, 0, N) for(auto x: lines[i]) lineId[x] = i; UnionFind UF(N), UFrev(N); vector<int> nxt(N, -1); for(auto [op, a, b]: Queries){ if(op == 2) continue; int lineA = lineId[a]; int lineB = lineId[b]; if(UF.find(lineA) != UF.find(lineB)){ // lineA ๋ค์ lineB ๋ถ์ด๊ธฐ int tailA = UFrev.find(lineA); int headB = UF.find(lineB); nxt[tailA] = headB; UF.merge(lineA, lineB); UFrev.merge(lineB, lineA); } } vector<int> mergedLineId(sz+1); vector<int> mergedLineIdx(sz+1); vector<vector<ll>> pfsum(N); rep(i, 0, N) if(UF.find(i) == i){ vector<int> order; int cur = i; while(cur != -1){ for(auto x: lines[cur]) order.push_back(x); cur = nxt[cur]; } for(int j = 0; j < (int)order.size(); j++){ mergedLineId[order[j]] = i; mergedLineIdx[order[j]] = j; } pfsum[i].resize(order.size()+1); rep(j, 0, order.size()) pfsum[i][j+1] = pfsum[i][j] + order[j]; } // ์ฟผ๋ฆฌ ์ฒ๋ฆฌ UnionFind UF2(N); for(auto [op, a, b]: Queries){ int lineA = lineId[a]; int lineB = lineId[b]; if(op == 1){ if(UF2.merge(lineA, lineB)) cout << "YES\n"; else cout << "NO\n"; } else{ if(UF2.find(lineA) != UF2.find(lineB)){ cout << "-1\n"; continue; } int mergedLine = mergedLineId[a]; int idxA = mergedLineIdx[a]; int idxB = mergedLineIdx[b]; if(idxA > idxB) swap(idxA, idxB); cout << pfsum[mergedLine][idxB+1] - pfsum[mergedLine][idxA] << "\n"; } } } ๐ ๊ตฌํ ์ฝ๋ ์ ๊ธ
·152 words·1 min
๐ ๋ฌธ์ ์ ๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/1647 ๐ง ๊ด์ฐฐ ๋ฐ ์ ๊ทผ # ์ง (์ ์ )๊ณผ ๊ธธ (๊ฐ์ )์ด ์๋ค. ๋ง์ ๋๊ฐ๋ก ๋ถ๋ฆฌํด์ผํ๋ค. ์ด ๋, ๊ฐ์ ์ ๊ฐ์ค์น์ ํฉ์ ์ต์ํํด์ผํ๋ค. ์ด๋ฏธ ๋ ์ง์ด ํ ๋ง์ ์์ ์๋ค๋ฉด, ๋์ด ์ฐ๊ฒฐํ ํ์๊ฐ ์๋ค. ์ด๋ฏธ ๋ค๋ฅธ ์ฐํ๋ก๋ก ๊ฐ ์ ์๊ธฐ ๋๋ฌธ ์ฐ๊ฒฐํ๋ ๋์ค ๋ง์์ด ๋๊ฐ๊ฐ ๋จ์๋ค๋ฉด ๋๋ด๋ฉด ๋๋ค. ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๋ฉ์ด๋ฆฌ๊ฐ ๋๊ฐ๊ฐ ๋จ์๋๊น์ง ๋ฐ๋ณตํ๋ฉด ๋๊ฒ ๋ค. ๐ป ํ์ด # ์ฝ๋ (C++): void solve(){ int N, M; cin >> N >> M; vector<tuple<int, int, int>> edges; // weight, u, v rep(i, 0, M){ int u, v, w; cin >> u >> v >> w; edges.emplace_back(w, u, v); } UF.init(N+1); sort(all(edges)); int ans = 0; for(auto &[w, u, v]: edges){ if(UF.group == 3) break; if(UF.merge(u, v)) ans += w; } cout << ans << "\n"; } ๐ ๊ตฌํ ์ฝ๋ ์ ๊ธ
·145 words·1 min
๐ ๋ฌธ์ ์ ๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/10775 ๐ง ๊ด์ฐฐ ๋ฐ ์ ๊ทผ # 1๋ฒ ๊ฒ์ดํธ๊ฐ ์ ์ผ ์ฐ๊ธฐ ์ข์๋ณด์ธ๋ค. ๊ทธ๋ฌ๋ฏ๋ก 1๋ฒ ๊ฒ์ดํธ๋ฅผ ์๋๋ค๊ณ ์๊ฐํ๋ฉด, ๋ชจ๋ ๋นํ๊ธฐ๋ฅผ ๋ํน์ํฌ๋ ๊ฐ ์ ์๋ ์ต๋๊ฐ์ผ๋ก ๋ํน์ํค๋ฉด ๋๋ ๊ฒ ๊ฐ๋ค. ์ด๋ฅผ ๋์ด๋ธํ๊ฒ ๊ตฌํํ๋ฉด ํ๋ฒ๋น $O(G)$๊ฐ ๊ฑธ๋ฆด ๊ฒ์ด๋ค. 100000 100000 100000 100000 100000 ... ๊ณผ ๊ฐ์ ํ
์คํธ์ผ์ด์ค๋ฅผ ์๊ฐํด๋ณด๋ฉด ๋๋ค. ๋ฐ๋ผ์ $\text{calc}(g_i) = g_i$ ๋ณด๋ค ์๊ฑฐ๋ ๊ฐ์ ์ด์์๋ ๊ฒ์ดํธ์ ์ต๋๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ์ผ๋ฉด ๋๋ค. ์ด๋ ์ ๋์จํ์ธ๋๋ก ๋น ๋ฅด๊ฒ ์ํ ๊ฐ๋ฅํ๋ค! mergeํ ๋ ์์ ๋ณด๋ค ์์ ๊ฐ์ ๊ฐ๋ฆฌํค๊ฒ ํ์. ๐ป ํ์ด # ์ฝ๋ (C++): void solve(){ int G, P; cin >> G >> P; UF.init(G+1); int ans = 0; while(P--){ int g; cin >> g; int rt = UF.find(g); if(rt == 0) break; UF.merge(rt, rt-1); ans++; } cout << ans << "\n"; } ๐ ๊ตฌํ ์ฝ๋ ์ ๊ธ
·161 words·1 min
๐ ๋ฌธ์ ์ ๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/1043 ๐ง ๊ด์ฐฐ ๋ฐ ์ ๊ทผ # ์ง๋ฏผ์ด๋ ๋ชจ๋ ํํฐ์ ์ฐธ์ฌํด์ผํ๋ฏ๋ก, ์ง์ค์ ์๋ ์ฌ๋์ด ์๋ ํํฐ์ ๋ชจ๋ ์ฌ๋์ ์ง์ค์ ์๊ฒ ๋๋ค. ๋ชจ๋ ํํฐ์ ๋ํด ์ง์ค์ ์๊ฒ ๋ ์ฌ๋์ ํ์ธํ ํ, ์ง์ค์ ์๋์ฌ๋์ด ์๋ ํํฐ๋ค์ ์๋ฅผ ์ธ๋ฉด ๋๋ค. ์ ๋์จ ํ์ธ๋, ๋ถ๋ฆฌ ์งํฉ์ผ๋ก ํด๊ฒฐํ์. ๐ป ํ์ด # ์ฝ๋ (C++): void solve(){ int N, M; cin >> N >> M; vector<vector<int>> parties; UnionFind UF(N+1); // 0์ ์ง์ค์ ์๋ ์ฌ๋ int cnt; cin >> cnt; rep(i, 0, cnt){ int a; cin >> a; UF.merge(0, a); } rep(i, 0, M){ cin >> cnt; vector<int> party(cnt); rep(j, 0, cnt) cin >> party[j]; parties.push_back(party); rep(j, 0, cnt-1) UF.merge(party[j], party[j+1]); } int ans = 0; for(auto party: parties){ bool flag = true; for(auto p: party) if(UF.find(p) == 0) flag = false; if(flag) ans++; } cout << ans; } ๐ ๊ตฌํ ์ฝ๋ ์ ๊ธ