結果
| 問題 | No.3561 Collect KCPC |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-05-29 20:05:36 |
| 言語 | C++17 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 193 ms / 6,000 ms |
| コード長 | 3,708 bytes |
| 記録 | |
| コンパイル時間 | 1,905 ms |
| コンパイル使用メモリ | 235,928 KB |
| 実行使用メモリ | 30,108 KB |
| 最終ジャッジ日時 | 2026-05-29 20:05:48 |
| 合計ジャッジ時間 | 8,795 ms |
|
ジャッジサーバーID (参考情報) |
judge3_0 / judge4_0 |
| 純コード判定待ち |
(要ログイン)
| サブタスク | 配点 | 結果 |
|---|---|---|
| 部分点1 | 10 % | AC * 15 |
| 部分点2 | 20 % | AC * 15 |
| 部分点3 | 20 % | AC * 13 |
| 部分点4 | 50 % | AC * 51 |
| 合計 | 100 点 |
ソースコード
#include <bits/stdc++.h>
#include <atcoder/modint.hpp>
using namespace std;
using i32 = int;
using i64 = long long;
using i128 = __int128_t;
using f64 = double;
using p2 = pair<i64, i64>;
using p3 = tuple<i64, i64, i64>;
using mint = atcoder::modint998244353;
constexpr i64 inf = 1e18;
void _main();
int main() {
cin.tie(0);
ios::sync_with_stdio(false);
cout << fixed << setprecision(18);
_main();
}
void _main() {
i64 n, m;
cin >> n >> m;
vector<vector<p2>> g(n), h(n);
for (i64 i = 0; i < m; i++) {
i64 u, v, c;
cin >> u >> v >> c;
u--, v--;
g[u].push_back({v, c});
h[v].push_back({u, c});
}
string s;
cin >> s;
vector<vector<p2>> dp1(n, {{inf, inf}, {inf + 1, inf + 1}});
{
priority_queue<p3, vector<p3>, greater<p3>> que;
auto merge = [&](i64 i, p2 x) -> bool {
if (dp1[i][0].first > x.first) {
if (dp1[i][0].second != x.second) dp1[i] = {x, dp1[i][0]};
else dp1[i] = {x, dp1[i][1]};
return true;
} else if (dp1[i][0].second != x.second && dp1[i][1].first > x.first) {
dp1[i] = {dp1[i][0], x};
return true;
}
return false;
};
for (i64 i = 0; i < n; i++) {
if (s[i] == 'C') {
que.push({0, i, i});
merge(i, {0, i});
}
}
while (!que.empty()) {
auto [d, i, j] = que.top();
que.pop();
if (dp1[i][0] != (p2){d, j} && dp1[i][1] != (p2){d, j}) continue;
for (auto [ni, c] : h[i]) {
if (merge(ni, {d + c, j})) {
que.push({d + c, ni, j});
}
}
}
for (i64 i = 0; i < n; i++) {
if (s[i] != 'P') dp1[i] = {{inf, inf}, {inf + 1, inf + 1}};
}
}
vector<i64> dp2(n, inf);
{
priority_queue<p3, vector<p3>, greater<p3>> que;
auto merge = [&](i64 i, p2 x) -> bool {
if (dp1[i][0].first > x.first) {
if (dp1[i][0].second != x.second) dp1[i] = {x, dp1[i][0]};
else dp1[i] = {x, dp1[i][1]};
return true;
} else if (dp1[i][0].second != x.second && dp1[i][1].first > x.first) {
dp1[i] = {dp1[i][0], x};
return true;
}
return false;
};
for (i64 i = 0; i < n; i++) {
if (s[i] == 'P') {
for (auto [x, j] : dp1[i]) {
que.push({x, i, j});
}
}
}
while (!que.empty()) {
auto [d, i, j] = que.top();
que.pop();
if (dp1[i][0] != (p2){d, j} && dp1[i][1] != (p2){d, j}) continue;
for (auto [ni, c] : h[i]) {
if (merge(ni, {d + c, j})) {
que.push({d + c, ni, j});
}
}
}
for (i64 i = 0; i < n; i++) {
if (s[i] == 'C') {
dp2[i] = dp1[i][0].second != i ? dp1[i][0].first : dp1[i][1].first;
} else dp2[i] = inf;
}
}
{
priority_queue<p2, vector<p2>, greater<p2>> que;
for (i64 i = 0; i < n; i++) {
if (s[i] == 'C') {
que.push({dp2[i], i});
}
}
while (!que.empty()) {
auto [d, i] = que.top();
que.pop();
if (dp2[i] < d) continue;
for (auto [ni, c] : h[i]) {
if (dp2[ni] > d + c) {
dp2[ni] = d + c;
que.push({d + c, ni});
}
}
}
for (i64 i = 0; i < n; i++) {
if (s[i] != 'K') dp2[i] = inf;
}
}
{
priority_queue<p2, vector<p2>, greater<p2>> que;
for (i64 i = 0; i < n; i++) {
if (s[i] == 'K') {
que.push({dp2[i], i});
}
}
while (!que.empty()) {
auto [d, i] = que.top();
que.pop();
if (dp2[i] < d) continue;
for (auto [ni, c] : h[i]) {
if (dp2[ni] > d + c) {
dp2[ni] = d + c;
que.push({d + c, ni});
}
}
}
}
cout << (dp2[0] >= inf ? -1 : dp2[0]) << "\n";
}