반응형
https://www.acmicpc.net/problem/1178
1178번: 간선 추가
첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (2 ≤ V ≤ 1,000, 1 ≤ E ≤ V×(V-1)/2) 정점에는 1부터 V까지 번호가 매겨져 있다고 생각한다. 이어서 E개의 줄에 걸쳐 간선을 이루는 두 점 a와 b
www.acmicpc.net
1. 문제설명
주어진 그래프를 오일러 회로 or 오일러 경로로 만드려면
몇개의 간선이 추가로 필요한지 구해야 하는 문제입니다.
2. 접근방법[알고리즘]
주어진 그래프에서
Union & Find 알고리즘을 이용해
서로 다른 컴포넌트면서 차수가 0이거나 홀수인 노드를 우선 연결해주고
그 이후에도 서로 다른 컴포넌트가 남아있다면
컴포넌트 개수가 1이 될 때까지 모두 연결해준뒤
한붓그리기가 가능한
오일러 회로나 오일러 경로가 되려면
차수가 홀수인 노드가 최대 2개여야 하므로
차수가 홀수인 노드의 개수를 센 다음에
간선을 몇개 더 이어줘야하는지 구하면 답을 구할 수 있습니다.
3.문제풀이코드 C++
#include <bits/stdc++.h>
using namespace std;
int v, e, area, ans;
int degree[1001];
int unf[1001];
int Find(int x) {
if (x == unf[x]) return x;
else {
return unf[x] = Find(unf[x]);
}
}
void Union(int a, int b) {
a = Find(a);
b = Find(b);
if (a != b) unf[a] = b;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> v >> e;
for (int i = 1; i <= v; i++) {
unf[i] = i;
}
for (int i = 0; i < e; i++) {
int a, b;
cin >> a >> b;
degree[a]++;
degree[b]++;
Union(a, b);
}
//1. 서로 다른 컴포넌트이며 둘 다 차수가 홀 수거나 0이면 이어준다.
for (int i = 1; i <= v; i++) {
for (int j = i + 1; j <= v; j++) {
if ((degree[i] % 2 == 1 || degree[i]==0) &&
(degree[j] % 2 == 1||degree[j]==0) &&
(Find(i) != Find(j))) {
Union(i, j);
degree[i]++;
degree[j]++;
ans++;
}
}
}
//2. 둘다 차수가 짝수여도 서로 다른 컴포넌트일 경우 서로 이어준다.
for (int i = 1; i <= v; i++) {
for (int j = i + 1; j <= v; j++) {
if (Find(i) != Find(j)) {
Union(i, j);
degree[i]++;
degree[j]++;
ans++;
}
}
}
int odd = 0;
for (int i = 1; i <= v; i++) {
if (degree[i] % 2 == 1) {
odd++;
}
}
//3. 차수가 홀 수 인 게 2개이상인 경우 그만큼 연결해주어야한다.
ans += (odd - 2 > 0) ? ((odd - 2) / 2) : 0;
cout << ans << '\n';
return 0;
}

반응형
'Algorithm > problem' 카테고리의 다른 글
백준 3197번 : 백조의 호수 BFS Union&Find C++ (0) | 2022.03.01 |
---|---|
백준 14868번 : 문명 - BFS Union&Find C++ (0) | 2022.03.01 |
백준 16168번 : 퍼레이드 - 오일러 회로 C++ (0) | 2022.02.28 |
백준 1199번: 오일러 회로 시간초과 해결 (0) | 2022.02.28 |
백준 18111번 : 마인크래프트 C++ 코드 (0) | 2022.02.26 |