結果
問題 | No.19 ステージの選択 |
ユーザー | pessimist |
提出日時 | 2024-10-22 15:26:29 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 2 ms / 5,000 ms |
コード長 | 2,751 bytes |
コンパイル時間 | 3,102 ms |
コンパイル使用メモリ | 221,340 KB |
実行使用メモリ | 6,824 KB |
最終ジャッジ日時 | 2024-10-22 15:26:33 |
合計ジャッジ時間 | 4,402 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,824 KB |
testcase_01 | AC | 2 ms
6,816 KB |
testcase_02 | AC | 2 ms
6,816 KB |
testcase_03 | AC | 2 ms
6,816 KB |
testcase_04 | AC | 2 ms
6,816 KB |
testcase_05 | AC | 2 ms
6,816 KB |
testcase_06 | AC | 2 ms
6,820 KB |
testcase_07 | AC | 2 ms
6,820 KB |
testcase_08 | AC | 2 ms
6,820 KB |
testcase_09 | AC | 2 ms
6,816 KB |
testcase_10 | AC | 2 ms
6,816 KB |
testcase_11 | AC | 2 ms
6,816 KB |
testcase_12 | AC | 2 ms
6,816 KB |
testcase_13 | AC | 2 ms
6,820 KB |
testcase_14 | AC | 2 ms
6,820 KB |
testcase_15 | AC | 2 ms
6,816 KB |
testcase_16 | AC | 2 ms
6,820 KB |
testcase_17 | AC | 2 ms
6,816 KB |
testcase_18 | AC | 2 ms
6,816 KB |
testcase_19 | AC | 2 ms
6,820 KB |
testcase_20 | AC | 2 ms
6,820 KB |
testcase_21 | AC | 2 ms
6,816 KB |
testcase_22 | AC | 2 ms
6,816 KB |
testcase_23 | AC | 2 ms
6,820 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; struct SCC{ int V = 0; vector<vector<int>> adj; vector<int> tour_index, low_link; int tour; vector<int> stack; vector<bool> in_stack; vector<vector<int>> components; vector<int> which_component; SCC(int v = 0) : V(v), adj(V, vector<int>()){} SCC(const vector<vector<int>>& adj_) : V(static_cast<int>(size(adj))), adj(adj) {} void add_edge(int a, int b){ adj[a].emplace_back(b); } //Tarjan's Algorithm void dfs(int node){ tour_index[node] = low_link[node] = tour++; stack.push_back(node); in_stack[node] = true; for(const int& neighbour: adj[node]){ if(tour_index[neighbour] < 0){ //neighbour is the part of subtree dfs(neighbour); low_link[node] = min(low_link[node], low_link[neighbour]); } else if(in_stack[neighbour]){ // neighbour is our tree ancestor, so it's a candidate for minimizing low_link time for node low_link[node] = min(low_link[node], tour_index[neighbour]); } } if(low_link[node] == tour_index[node]){ // node is the highest node in a SCC, which includes everything on the stack up to it. components.emplace_back(); vector<int> &component = components.back(); int x; do{ assert(!stack.empty()); x = stack.back(); stack.pop_back(); in_stack[x] = false; component.emplace_back(x); which_component[x] = size(components) - 1; }while(x != node); } } void build(){ tour_index.assign(V, -1); low_link.assign(V, -1); which_component.assign(V, -1); stack.clear(); stack.reserve(V); in_stack.assign(V, false); tour = 0; //Note that Tarjan's Algorithm provides the SCCs in reverse topological order components = {}; for(int i=0; i<V; ++i) if(tour_index[i] < 0) dfs(i); } }; int main(){ cin.tie(nullptr)->sync_with_stdio(false); int N; cin >> N; vector<int> l(N), s(N); // (diff, stage that must be cleared before to halve the diff) SCC scc(N); for(int i = 0; i < N; ++i){ cin >> l[i] >> s[i]; --s[i]; scc.add_edge(s[i], i); l[i] *= 2; } scc.build(); int ans = 0; auto comp = scc.components; for(auto& c: comp){ vector<int> t; for(auto& v: c){ t.emplace_back(l[v]); } if(t.size() == 1){ if(s[c[0]] == c[0]){ ans += t[0]; } else{ ans += t[0] / 2; } } else{ sort(t.begin(), t.end()); for(int j = 0; j < t.size(); ++j){ if(j == 0) ans += t[j]; else ans += t[j] / 2; } } } cout << (ans >> 1); if(ans & 1) cout << ".5"; else cout << ".0"; cout << endl; return 0; }