結果
| 問題 |
No.2418 情報通だよ!Nafmoくん
|
| コンテスト | |
| ユーザー |
うえこ
|
| 提出日時 | 2023-08-12 13:46:49 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 66 ms / 2,000 ms |
| コード長 | 1,985 bytes |
| コンパイル時間 | 1,675 ms |
| コンパイル使用メモリ | 173,156 KB |
| 実行使用メモリ | 6,824 KB |
| 最終ジャッジ日時 | 2024-11-14 12:21:29 |
| 合計ジャッジ時間 | 3,366 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 21 |
ソースコード
#include <bits/stdc++.h>
const int INF=1<<30;
// Union-Find 木
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_parents[b] = a;
m_sizes[a] += m_sizes[b];
}
}
// 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 用)
std::vector<int> m_sizes;
};
int main(){
int n,m;
std::cin >> n >> m;
std::vector<std::pair<int,int>>V(m);
UnionFind uf(2*n);
for(auto&v:V){
std::cin >> v.first >> v.second;
--v.first;
--v.second;
uf.merge(v.first,v.second);
}
std::vector<int>sizes;
for(int i=0;i<2*n;++i){
if(uf.find(i)==i){
sizes.push_back(uf.size(i));
}
}
int remain=0;
int ans=0;
for(const auto&s:sizes){
if(s%2==0)continue;
if(remain==1){
remain=0;
}
else{
++remain;
++ans;
}
}
std::cout << ans << '\n';
}
うえこ