이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "cyberland.h"
#include <algorithm>
#include <iostream>
#include <numeric>
#include <cassert>
#include <vector>
#include <queue>
typedef long long llong;
const int MAXN = 100000 + 10;
const llong INF = 1e14;
const int INTINF = 1e9;
int n, m, k, h;
bool vis[MAXN];
llong dist[MAXN];
int ability[MAXN];
std::vector <std::pair <int,int>> g[MAXN];
std::priority_queue <std::pair <llong,int>> pq;
double toReach[MAXN];
void reset()
{
for (int i = 1 ; i <= n ; ++i)
{
g[i].clear();
dist[i] = ability[i] = 0;
toReach[i] = 0.0;
vis[i] = false;
}
while (!pq.empty())
{
pq.pop();
}
}
void dfs(int node)
{
vis[node] = true;
if (node == h)
{
return;
}
for (const auto &[u, e] : g[node])
{
if (vis[u])
{
continue;
}
dfs(u);
}
}
double solve(int N, int M, int K, int H, std::vector <int> x, std::vector <int> y, std::vector <int> c, std::vector <int> arr)
{
reset();
n = N;
m = M;
k = K;
h = H + 1;
for (int i = 0 ; i < m ; ++i)
{
g[x[i] + 1].emplace_back(y[i] + 1, c[i]);
g[y[i] + 1].emplace_back(x[i] + 1, c[i]);
}
dfs(1);
if (!vis[h])
{
return -1;
}
for (int i = 2 ; i <= n ; ++i)
{
ability[i] = arr[i - 1];
}
std::fill(dist + 1, dist + 1 + n, INF);
for (int i = 1 ; i <= n ; ++i)
{
if (!vis[i]) continue;
if (ability[i] == 0)
{
dist[i] = 0;
pq.push({0, i});
}
}
std::fill(vis + 1, vis + 1 + n, false);
while (!pq.empty())
{
auto [currDist, node] = pq.top();
pq.pop();
if (vis[node])
{
continue;
}
vis[node] = true;
if (node != h)
{
for (const auto &[u, e] : g[node])
{
if (dist[u] > dist[node] + e)
{
dist[u] = dist[node] + e;
pq.push({-dist[u], u});
}
}
}
}
for (int i = 1 ; i <= n ; ++i)
{
toReach[i] = dist[i];
if (ability[i] == 2)
{
int minEdge = INTINF;
for (const auto &[u, e] : g[i])
{
if (u == h)
{
continue;
}
minEdge = std::min(minEdge, e);
}
toReach[i] /= 2.0;
if (k > 60)
{
toReach[i] = std::min(toReach[i], (double)2*minEdge);
break;
}
for (int j = 1 ; j < k && toReach[i] >= 2*minEdge ; ++j)
{
toReach[i] /= 2.0;
toReach[i] += minEdge;
}
}
}
std::fill(vis + 1, vis + 1 + n, false);
std::fill(dist + 1, dist + 1 + n, INF);
pq.push({0, h});
dist[h] = 0;
while (!pq.empty())
{
auto [currDist, node] = pq.top();
pq.pop();
if (vis[node])
{
continue;
}
vis[node] = true;
for (const auto &[u, e] : g[node])
{
if (dist[u] > dist[node] + e)
{
dist[u] = dist[node] + e;
pq.push({-dist[u], u});
}
}
}
double ans = INF;
for (int i = 1 ; i <= n ; ++i)
{
ans = std::min(ans, (double)dist[i] + toReach[i]);
}
return ans;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |