이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
// #include "factories.h"
using namespace std;
#define num long long
#define t_road pair<int, num>
#define rnext first
#define rcost second
#define t_roads set<t_road>
#define graph vector<t_roads>
#define idata vector<int>
#define ndata vector<num>
#define ngrid vector<ndata>
#define inf 1e18
int nbNodes, nbQuery;
graph roads;
idata centroid_tree;
idata subtree_size;
ngrid centroid_tree_distances;
int subtree_dfs (int node, int parent) {
subtree_size[node] = 1;
for (t_road road : roads[node]) if (road.rnext != parent)
subtree_size[node] += subtree_dfs(road.rnext, node);
return subtree_size[node];
}
int centroid (int node, int parent, int compSize) {
for (t_road road : roads[node])
if (road.rnext != parent
&& subtree_size[road.rnext] > compSize)
return centroid(road.rnext, node, compSize);
return node;
}
void update_distances (int node, int parent, num distance) {
centroid_tree_distances[node].push_back(distance);
for (t_road road : roads[node]) if (road.rnext != parent)
update_distances(road.rnext, node, distance + road.rcost);
}
void decompose (int node, int parent) {
int c_size = subtree_dfs(node, -1);
int centri = centroid(node, -1, c_size >> 1);
update_distances(centri, -1, 0);
centroid_tree[centri] = parent;
while (roads[centri].size() != 0) {
t_road road = *(roads[centri].begin());
roads[centri].erase(road);
roads[road.rnext].erase({ centri, road.rcost });
decompose(road.rnext, centri);
}
}
ndata query_metadata;
void enable (int start) {
int id = 0;
int node = start;
while (node != -1) {
query_metadata[node] = min(
query_metadata[node],
centroid_tree_distances[start][id]
);
node = centroid_tree[node];
id ++;
}
}
void reset (int node) {
while (node != -1) {
query_metadata[node] = inf;
node = centroid_tree[node];
}
}
num query (int start) {
num res = inf;
int id = 0;
int node = start;
while (node != -1) {
res = min(
res,
query_metadata[node] + centroid_tree_distances[start][id]
);
node = centroid_tree[node];
id ++;
}
return res;
}
void Init(int N, int A[], int B[], int D[]) {
nbNodes = N;
roads.resize(nbNodes);
centroid_tree.resize(nbNodes);
subtree_size .resize(nbNodes);
centroid_tree_distances.resize(nbNodes);
query_metadata.resize(nbNodes, inf);
for (int iR = 0; iR + 1 < nbNodes; iR ++) {
roads[A[iR]].insert({ B[iR], D[iR] });
roads[B[iR]].insert({ A[iR], D[iR] });
}
decompose(0, -1);
for (int i = 0; i < nbNodes; i ++)
reverse(centroid_tree_distances[i].begin(), centroid_tree_distances[i].end());
}
num Query(int S, int X[], int T, int Y[]) {
for (int i = 0; i < S; i ++) enable(X[i]);
num res = inf;
for (int i = 0; i < T; i ++)
res = min(res, query(Y[i]));
for (int i = 0; i < S; i ++) reset (X[i]);
return res;
}
/*int main () {
ios_base::sync_with_stdio(false); cin.tie(NULL);
cin >> nbNodes >> nbQuery;
roads.resize(nbNodes);
centroid_tree.resize(nbNodes);
subtree_size .resize(nbNodes);
centroid_tree_distances.resize(nbNodes);
query_metadata.resize(nbNodes, inf);
for (int iR = 1; iR < nbNodes; iR ++) {
int a, b, c;
cin >> a >> b >> c;
roads[a].insert({ b, c });
roads[b].insert({ a, c });
}
decompose(0, -1);
for (int i = 0; i < nbNodes; i ++)
reverse(centroid_tree_distances[i].begin(), centroid_tree_distances[i].end());
for (int iQ = 0; iQ < nbQuery; iQ ++) {
int s, t;
cin >> s >> t;
vector<int> S(s);
for (int iS = 0; iS < s; iS ++) cin >> S[iS];
for (int vS : S) enable(vS);
num res = inf;
for (int iT = 0; iT < t; iT ++) {
int vT; cin >> vT;
res = min(res, query(vT));
}
cout << res << endl;
for (int vS : S) reset (vS);
}
}*/
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |