본문 바로가기

Problem Solving/문제풀이

[BOJ] 14591 KUBC League, 17165 Gosu

14591 KUBC League

문제 요약

토너먼트 그래프가 있다. 1번 정점에서 시작해서 모든 정점을 순회하는 단순 경로를 찾으면 된다.

문제 풀이

DFS 스패닝 트리에 의거하여, 그냥 DFS를 1번 정점에서부터 수행 후 마지막부터 출력해주면 된다!

코드

#include <bits/stdc++.h>
#include <random>
#include <cassert>
#define all(x) (x).begin(), (x).end()
#define endl "\n"
#define ends " "
#define pb(x) push_back(x)
#define fio() ios_base::sync_with_stdio(0); cin.tie(0)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef tuple<int, int, int> tpi;
typedef tuple<ll, ll, ll> tpl;

using namespace std;

int chk[2020];
int adj[2020][2020];
vector<int> ans;

int n;
void dfs(int x) {
	chk[x] = 1;
	for (int i = 1; i <= n; i++)
		if (!chk[i] && adj[x][i]) dfs(i);
	ans.push_back(x);
}

int main() {
	fio();
	cin >> n;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			cin >> adj[i][j];
	dfs(1);
	cout << ans.size() << endl;
	reverse(all(ans));
	for (int x : ans) cout << x << ends;
}

17165 Gosu

문제 요약

토너먼트 그래프가 있다. 어떤 정점 x의 태보 레벨을 x에서부터의 다른 정점까지의 최단경로 길이 중 최댓값이라고 정의하자. 이때 가장 태보 레벨이 작은 사람과 그 때의 태보 레벨을 구해야 한다.

문제 풀이

잘 생각해 보면 태보 레벨의 최댓값이 그렇게 길지 않을 것 같고, 실제로 레벨이 3 이상이 될 수 있다고 가정하고 귀류법을 걸면 모순이다. (또한 이 때 태보 레벨이 가장 작은 사람은 outdegree가 가장 큰 사람이다.) 따라서 한 사람이 모두를 이길 수 있으면 태보 레벨은 1, 아니라면 2이다. 코드는 이걸 미처 깨닫지 못해 더 복잡하게 작성되어 있다.

코드

#include <bits/stdc++.h>
#include <random>
#include <cassert>
#define all(x) (x).begin(), (x).end()
#define endl "\n"
#define ends " "
#define pb(x) push_back(x)
#define fio() ios_base::sync_with_stdio(0); cin.tie(0)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef tuple<int, int, int> tpi;
typedef tuple<ll, ll, ll> tpl;

using namespace std;

string adj[3005];
int dist[3005], win[3005];

int main() {
	fio();
	int n; cin >> n;
	for (int i = 0; i < n; i++) cin >> adj[i];
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			win[i] += adj[i][j] == 'W' ? 1 : 0;
	int ma=0, mai=0;
	for (int i = 0; i < n; i++)
		if (win[i] > ma)
			ma = win[i], mai = i;
	queue<int> Q; Q.push(mai); dist[mai] = 1;
	while (!Q.empty()) {
		int hr = Q.front(); Q.pop();
		for (int i = 0; i < n; i++) {
			if (dist[i] || adj[hr][i] != 'W') continue;
			dist[i] = dist[hr] + 1;
			Q.push(i);
		}
	}
	ma = *max_element(dist, dist + n);
	cout << ma - 1 << ends << mai + 1;
	return 0;
}

'Problem Solving > 문제풀이' 카테고리의 다른 글

[BOJ] 15404 Divide and Conquer  (0) 2020.08.10
[BOJ] 16910 mex와 쿼리  (1) 2020.03.22
[BOJ] 13329 Meteor Shower  (0) 2020.02.04
[ICPC] ICL 2016 (GP of Tatarstan) 후기 & 잡설들  (0) 2020.01.31
[BOJ] 10264 Particle Swapping  (0) 2020.01.24

태그