結果

問題 No.19 ステージの選択
ユーザー masamasa
提出日時 2015-01-29 03:39:18
言語 C++11
(gcc 11.4.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
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,816 KB
testcase_01 AC 2 ms
6,820 KB
testcase_02 AC 2 ms
6,820 KB
testcase_03 AC 2 ms
6,820 KB
testcase_04 AC 2 ms
6,816 KB
testcase_05 AC 2 ms
6,816 KB
testcase_06 AC 1 ms
6,820 KB
testcase_07 AC 2 ms
6,816 KB
testcase_08 AC 2 ms
6,820 KB
testcase_09 AC 2 ms
6,816 KB
testcase_10 AC 2 ms
6,820 KB
testcase_11 AC 2 ms
6,816 KB
testcase_12 AC 2 ms
6,816 KB
testcase_13 AC 2 ms
6,816 KB
testcase_14 AC 2 ms
6,816 KB
testcase_15 AC 2 ms
6,816 KB
testcase_16 AC 2 ms
6,816 KB
testcase_17 AC 2 ms
6,820 KB
testcase_18 AC 2 ms
6,816 KB
testcase_19 AC 2 ms
6,816 KB
testcase_20 AC 2 ms
6,816 KB
testcase_21 AC 2 ms
6,820 KB
testcase_22 AC 2 ms
6,816 KB
testcase_23 AC 1 ms
6,820 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#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;
}
0