結果

問題 No.19 ステージの選択
ユーザー masa
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

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