結果
| 問題 |
No.19 ステージの選択
|
| ユーザー |
atn112323
|
| 提出日時 | 2016-05-06 11:35:58 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 5,000 ms |
| コード長 | 1,684 bytes |
| コンパイル時間 | 692 ms |
| コンパイル使用メモリ | 69,152 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-12-23 10:05:08 |
| 合計ジャッジ時間 | 1,658 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 24 |
ソースコード
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
class UnionFindTree {
public:
explicit UnionFindTree(int size) {
size_ = size;
parent_ = new int[size];
rank_ = new int[size];
init();
}
~UnionFindTree() {
delete parent_;
delete rank_;
}
void init() {
for (int i = 0; i < size_; i++) {
parent_[i] = i;
rank_[i] = 0;
}
}
int find(int x) {
if (parent_[x] == x) {
return x;
} else {
return parent_[x] = find(parent_[x]);
}
}
void unite(int x, int y) {
x = find(x);
y = find(y);
if (x != y) {
if (rank_[x] < rank_[y]) {
parent_[x] = y;
} else {
parent_[y] = x;
if (rank_[x] == rank_[y]) {
rank_[x]++;
}
}
}
}
bool same(int x, int y) {
return find(x) == find(y);
}
private:
int size_;
int* parent_;
int* rank_;
};
const int INF = 1000000;
int N;
int L[100], S[100];
bool used[100];
int cnt[100];
int main() {
cin >> N;
for (int i = 0; i < N; i++) {
cin >> L[i] >> S[i];
S[i]--;
}
UnionFindTree uft(N);
for (int i = 0; i < N; i++) {
uft.unite(i, S[i]);
cnt[S[i]]++;
}
int res = 0;
for (int i = 0; i < N; i++) {
if (used[i]) {
continue;
}
queue<int> Q;
for (int j = i; j < N; j++) {
if (uft.same(i, j)) {
res += L[j];
used[j] = true;
if (cnt[j] == 0) {
Q.push(j);
}
}
}
while (!Q.empty()) {
int idx = Q.front();
Q.pop();
if (--cnt[S[idx]] == 0) {
Q.push(S[idx]);
}
}
int m = INF;
for (int j = i; j < N; j++) {
if (uft.same(i, j) && cnt[j] > 0) {
m = min(m, L[j]);
}
}
if (m < INF) {
res += m;
}
}
cout << res / 2 << "." << (res % 2 ? "5" : "0") << endl;
return 0;
}
atn112323