結果
| 問題 |
No.2563 色ごとのグループ
|
| コンテスト | |
| ユーザー |
ななな
|
| 提出日時 | 2023-12-02 19:44:24 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 365 ms / 2,000 ms |
| コード長 | 1,713 bytes |
| コンパイル時間 | 1,718 ms |
| コンパイル使用メモリ | 181,208 KB |
| 実行使用メモリ | 29,184 KB |
| 最終ジャッジ日時 | 2024-09-26 21:32:52 |
| 合計ジャッジ時間 | 6,773 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 35 |
ソースコード
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define rep(i, n) for (int i = 0; i < n; i++)
class UnionFind {
public:
UnionFind() = default;
// n 個の要素
explicit UnionFind(size_t n) : m_parents(n), m_sizes(n, 1) {
std::iota(m_parents.begin(), m_parents.end(), 0);
}
// i の root を返す
int find(int i) {
if (m_parents[i] == i) {
return i;
}
// 経路圧縮
return (m_parents[i] = find(m_parents[i]));
}
// a の木と b の木を統合
void merge(int a, int b) {
a = find(a);
b = find(b);
if (a != b) {
// union by size (小さいほうが子になる)
if (m_sizes[a] < m_sizes[b]) {
std::swap(a, b);
}
m_sizes[a] += m_sizes[b];
m_parents[b] = a;
}
}
// a と b が同じ木に属すかを返す
bool connected(int a, int b) { return (find(a) == find(b)); }
// i が属するグループの要素数を返す
int size(int i) { return m_sizes[find(i)]; }
private:
// m_parents[i] は i の 親,
// root の場合は自身が親
std::vector<int> m_parents;
// グループの要素数 (root 用)
// i が root のときのみ, m_sizes[i] はそのグループに属する要素数を表す
std::vector<int> m_sizes;
};
signed main() {
int n, m;
cin >> n >> m;
UnionFind uf(n);
vector<int> c(n);
rep(i, n) cin >> c[i];
rep(i, m) {
int u, v;
cin >> u >> v;
if (c[u - 1] == c[v - 1]) {
uf.merge(u - 1, v - 1);
}
}
map<int, set<int>> mp;
rep(i, n) {
int t = uf.find(i);
mp[c[i]].insert(t);
}
int ans = 0;
for (auto v : mp) {
int t = v.second.size();
ans += t - 1;
}
cout << ans << endl;
}
ななな