AtCoder Beginner Contest C - Path Graph?
問題はこちら
回答
UnionFind or BFS/DFS
以下のコードはUnionFind
#include <iostream>
#include <string>
#include <map>
#include <unordered_map>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <limits.h>
#include <bitset>
#include <list>
#include <set>
#include <numeric>
#include <tuple>
#include <iomanip>
#include <random>
int N, M;
class UnionFind {
private:
int size;
std::vector<int> parent;
std::vector<int> rank;
public:
UnionFind(const int n) {
size = n;
parent.resize(size);
rank.resize(size);
for (int i = 0; i < size; i++) {
parent[i] = i;
rank[i] = 0;
}
}
int GetRoot(const int& val) {
if (val == parent[val]) {
return val;
}
else {
parent[val] = GetRoot(parent[val]);
return parent[val];
}
}
void Merge(const int& val1, const int& val2) {
int root1 = GetRoot(val1);
int root2 = GetRoot(val2);
if (root1 == root2) {
return;
}
if (rank[root1] > rank[root2]) {
parent[root2] = root1;
}
else {
if (rank[root1] == rank[root2]) {
rank[root2]++;
}
parent[root1] = root2;
}
}
bool IsAllSame() {
int ref = GetRoot(parent[0]);
for (int i = 1; i < size; i++) {
if (ref != GetRoot(parent[i])) {
return false;
}
}
return true;
}
};
int main()
{
std::cin.tie(0);
std::ios::sync_with_stdio(false);
std::cin >> N >> M;
// グラフの条件
// 全ての頂点が同じグループに所属すること(全ての頂点が連結していること)
// →Union Find or BFS/DFS
// 次数が1の頂点数が2個(端点)
// 次数が2の頂点がN-2個
std::vector<int> indeg(N);
UnionFind uf(N);
for (int m = 0; m < M; m++) {
int u, v;
std::cin >> u >> v;
u--;
v--;
// 入次数カウント
indeg[u]++;
indeg[v]++;
// ufでu,vを連結
uf.Merge(u, v);
}
if (N - 1 != M) {
std::cout << "No" << std::endl;
return 0;
}
int numOne = 0;
int numTwo = 0;
for (int i = 0; i < N; i++) {
if (indeg[i] == 1) {
numOne++;
}
else if (indeg[i] == 2) {
numTwo++;
}
}
if (numOne != 2 || numTwo != N - 2) {
std::cout << "No" << std::endl;
return 0;
}
if (!uf.IsAllSame()) {
std::cout << "No" << std::endl;
return 0;
}
std::cout << "Yes" << std::endl;
return 0;
}