// Author: 4uckd3v - Nguyen Cao Duc
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX_N = 5e5;
const int MOD = 1e9 + 7;
const int INF = 1e9;
template <class X, class Y>
bool minimize(X &x, const Y &y) {
if (x <= y) return false;
x = y;
return true;
};
int n, k, timer, lg;
int sheepIdx[MAX_N + 5], depth[MAX_N + 5], tin[MAX_N + 5], tout[MAX_N + 5];
int up[MAX_N + 5][21];
vector<int> adj[MAX_N + 5];
namespace ConstructLCA {
bool ok = false;
void preDfs(int u, int par) {
tin[u] = ++timer;
up[u][0] = par;
depth[u] = depth[par] + 1;
for (int i = 1; i <= lg; i++)
up[u][i] = up[up[u][i - 1]][i - 1];
for (int v : adj[u]) {
if (v == par) continue;
preDfs(v, u);
};
tout[u] = ++timer;
};
void construct() {
ok = true;
lg = ceil(log2(n));
preDfs(1, 1);
};
}; // namespace ConstructLCA
bool isAncestor(int u, int v) {
assert(ConstructLCA::ok);
return tin[u] <= tin[v] && tout[u] >= tout[v];
};
int __lca(int u, int v) {
assert(ConstructLCA::ok);
if (isAncestor(u, v)) return u;
if (isAncestor(v, u)) return v;
for (int i = lg; i >= 0; i--)
if (!isAncestor(up[u][i], v))
u = up[u][i];
return up[u][0];
};
int dist(int u, int v) {
assert(ConstructLCA::ok);
return depth[u] + depth[v] - 2 * depth[__lca(u, v)];
};
namespace SUBTASK_1 {
const int N = 5e5;
int dp[N + 5];
bool checkSubtask() {
for (int u = 1; u <= n; u++)
if (adj[u].size() > 2) return false;
return true;
};
void trace(int i) {
vector<int> t;
while (i > 0) {
if (dp[i] == dp[i - 1] + 1) {
t.push_back(sheepIdx[i]);
i--;
} else {
int prevIdx = sheepIdx[i - 1];
int curIdx = sheepIdx[i];
t.push_back((curIdx + prevIdx + 1) >> 1);
i -= 2;
};
};
for (int idx : t) cout << idx << ' ';
cout << '\n';
};
void Solve() {
for (int i = 1; i <= n; i++) dp[i] = INF;
dp[1] = 1;
for (int i = 2; i <= k; i++) {
int prevIdx = sheepIdx[i - 1];
int curIdx = sheepIdx[i];
if ((curIdx - prevIdx + 1) & 1) {
minimize(dp[i], dp[i - 2] + 1);
};
minimize(dp[i], dp[i - 1] + 1);
};
cout << dp[k] << '\n';
trace(k);
};
}; // namespace SUBTASK_1
namespace SUBTASK_2 {
const int N = MAX_N;
const int K = 15;
int dp[1 << K], node[1 << K], minDist[N + 5], msk[N + 5];
int dist[N + 5];
pair<int, bool> traceMask[1 << K];
void bfs(int s, int *dist) {
for (int u = 1; u <= n; u++) dist[u] = -1;
queue<int> q;
q.push(s);
dist[s] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int v : adj[u]) {
if (dist[v] == -1) {
dist[v] = dist[u] + 1;
q.push(v);
};
};
};
};
bool checkSubtask() {
return k <= K && n <= N;
};
void trace(int mask) {
while (mask > 0) {
int prevMask = traceMask[mask].first;
bool type = traceMask[mask].second;
if (type) cout << node[prevMask ^ mask] << ' ';
mask = prevMask;
};
};
void Solve() {
for (int mask = 0; mask < (1 << k); mask++) dp[mask] = INF;
for (int u = 1; u <= n; u++) minDist[u] = INF;
for (int i = 1; i <= k; i++) {
bfs(sheepIdx[i], dist);
for (int u = 1; u <= n; u++) {
if (minimize(minDist[u], dist[u])) {
msk[u] = 1 << (i - 1);
} else if (minDist[u] == dist[u]) {
msk[u] |= 1 << (i - 1);
};
};
};
dp[0] = 0;
for (int u = 1; u <= n; u++) {
if (msk[u] > 0) node[msk[u]] = u;
};
for (int mask = 0; mask < (1 << k); mask++) {
for (int subMask = mask; subMask > 0; subMask = (subMask - 1) & mask) {
if (node[subMask] == 0) continue;
if (minimize(dp[mask], dp[mask ^ subMask] + 1)) traceMask[mask] = {mask ^ subMask, 1};
};
for (int subMask = mask; subMask > 0; subMask = (subMask - 1) & mask) {
if (minimize(dp[subMask], dp[mask])) traceMask[subMask] = {mask, 0};
};
};
cout << dp[(1 << k) - 1] << '\n';
trace((1 << k) - 1);
};
}; // namespace SUBTASK_2
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
if (fopen("PASTIRI.INP", "r")) {
freopen("PASTIRI.INP", "r", stdin);
freopen("PASTIRI.OUT", "w", stdout);
};
cin >> n >> k;
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
};
for (int i = 1; i <= k; i++) {
cin >> sheepIdx[i];
};
sort(sheepIdx + 1, sheepIdx + k + 1);
if (SUBTASK_1::checkSubtask())
return SUBTASK_1::Solve(), 0;
if (SUBTASK_2::checkSubtask())
return SUBTASK_2::Solve(), 0;
};
컴파일 시 표준 에러 (stderr) 메시지
pastiri.cpp: In function 'int main()':
pastiri.cpp:201:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
201 | freopen("PASTIRI.INP", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
pastiri.cpp:202:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
202 | freopen("PASTIRI.OUT", "w", stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | 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... |