Problem Solving/문제풀이
[BOJ] 14591 KUBC League, 17165 Gosu
Ryute
2020. 3. 22. 21:08
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;
}