結果
| 問題 |
No.2418 情報通だよ!Nafmoくん
|
| コンテスト | |
| ユーザー |
u-sho
|
| 提出日時 | 2023-08-12 16:06:32 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 1,905 bytes |
| コンパイル時間 | 2,309 ms |
| コンパイル使用メモリ | 201,880 KB |
| 最終ジャッジ日時 | 2025-02-16 07:12:58 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 3 WA * 18 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
template <class Node>
class UnionFind {
std::vector<Node> parent;
public:
std::vector<Node> children_count;
/* サイズ n の素集合を作成: o(n) */
UnionFind(const std::size_t &n) : parent(n), children_count(n, 0) {
for (std::size_t i = 0; i < n; i++) parent[i] = Node(i);
}
/* ノード x が属する木の根を返す:𝑶(α(n)) */
[[nodiscard]] Node root(const Node &x) {
if (parent[x] == x) return x;
Node root_x = root(parent[x]);
children_count[parent[x]] -= children_count[x];
return parent[x] = root_x;
}
/* 木x と 木y を併合し成功したかを返す:𝑶(α(n)) */
bool merge(const Node &x, const Node &y) {
unsigned root_x = root(x);
unsigned root_y = root(y);
if (root_x == root_y) return false;
if (children_count[root_x] > children_count[root_y]) swap(root_x, root_y);
parent[root_x] = root_y;
if (children_count[root_x]) children_count[root_y] += children_count[root_x];
else children_count[root_y] += 1;
return true;
}
/* ノード x, y が属する木は同じか:𝑶(α(n)) */
[[nodiscard]] bool same(const Node &x, const Node &y) {
return root(x) == root(y);
}
};
int main(){
cin.tie(nullptr);
ios::sync_with_stdio(false);
uint N, M;
cin >> N >> M;
UnionFind<uint> uf(2*N+1);
for (uint i=1; i<= M; i++){
uint Ai, Bi;
cin >> Ai >> Bi;
uf.merge(Ai, Bi);
}
set<uint> roots;
uint non_paired = 0;
for (uint i=1; i<=2*N; i++){
uint root_i = uf.root(i);
if (roots.find(root_i) == roots.end()) {
roots.insert(root_i);
non_paired += (uf.children_count[root_i]+1) % 2;
}
}
cout << (non_paired+1U) / 2U << '\n';
return 0;
}
u-sho