結果
| 問題 |
No.19 ステージの選択
|
| ユーザー |
|
| 提出日時 | 2015-01-29 03:39:18 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 5,000 ms |
| コード長 | 1,828 bytes |
| コンパイル時間 | 1,041 ms |
| コンパイル使用メモリ | 85,476 KB |
| 実行使用メモリ | 6,820 KB |
| 最終ジャッジ日時 | 2024-12-23 10:01:05 |
| 合計ジャッジ時間 | 1,839 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 24 |
ソースコード
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <utility>
#include <set>
#include <queue>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> level(n+1, 0), prev(n+1, 0);
vector< vector<int> > next(n+1, vector<int>());
for (int i = 1; i <= n; i++) {
cin >> level[i] >> prev[i];
level[i] *= 10;
next[prev[i]].push_back(i);
}
// 非循環部分の計算と除去
int ans = 0;
bool update = true;
vector<bool> used(n+1, false);
used[0] = true;
vector<int>::iterator it;
int count = 0;
while(update) {
update = false;
for (int i = 1; i <= n; i++) {
if (!next[i].empty() || used[i]) {
continue;
}
used[i] = true;
ans += level[i] / 2;
update = true;
for (int j = 1; j <= n; j++) {
if (!next[j].empty()) {
for (it = next[j].begin(); it != next[j].end(); ) {
if (*it == i) {
next[j].erase(it);
} else {
it++;
}
}
}
}
}
}
// 循環ごとにまとめる
vector< set<int> > group;
for (int i = 0; i <= n; i++) {
if (used[i]) {
continue;
}
set<int> cycle;
queue<int> que;
for (que.push(i); !que.empty(); que.pop()) {
int num = que.front();
cycle.insert(num);
used[num] = true;
for (int i = 0; i < next[num].size(); i++) {
int tmp = next[num][i];
if (!used[tmp]) {
que.push(tmp);
}
}
}
group.push_back(cycle);
}
// 循環部分毎に最小になるように計算
for (int i = 0; i < group.size(); i++) {
int sum = 0;
int pos = 0;
int minlevel = 1e8;
for (auto its = group[i].begin(); its != group[i].end(); its++) {
sum += level[*its];
if (minlevel > level[*its]) {
minlevel = level[*its];
pos = *its;
}
}
ans += (sum - level[pos]) / 2 + level[pos];
}
printf("%.1f\n", 0.1 * ans);
return 0;
}