#include #include #include #include #include #include #include #include #include #include typedef long long llong; const int MAXN = 1000000 + 10; const int INTINF = 1e9; const llong INF = 1e18; const int MAXLOG = 17; int n; int sz[MAXN]; bool vis[MAXN]; int count[MAXN]; int depth[MAXN]; llong color[MAXN]; std::vector g[MAXN]; std::vector c[MAXN]; std::unordered_map compr; int colorCnt; void calcSize(int node, int par) { sz[node] = 1; for (const int &u : g[node]) { if (u == par || vis[u]) { continue; } calcSize(u, node); sz[node] += sz[u]; } } int findCentroid(int node, int par, int compSZ) { for (const int &u : g[node]) { if (u != par && !vis[u] && sz[u] > compSZ / 2) { return findCentroid(u, node, compSZ); } } return node; } int decompose(int node, int dep) { // std::cout << "decompose: " << node << '\n'; calcSize(node, 0); int cntr = findCentroid(node, 0, sz[node]); depth[cntr] = dep; vis[cntr] = true; for (const int &u : g[cntr]) { if (vis[u]) { continue; } c[cntr].push_back(decompose(u, dep + 1)); } return cntr; } int min = INTINF; int max = -INTINF; int minCNT[MAXN]; int maxCNT[MAXN]; void clearMinMax(int node) { minCNT[color[node]] = INTINF; maxCNT[color[node]] = -INTINF; for (const int &u : c[node]) { clearMinMax(u); } } void addMinMax(int node, int par, int dist, int allowedTo) { minCNT[color[node]] = std::min(minCNT[color[node]], dist); maxCNT[color[node]] = std::max(maxCNT[color[node]], dist); for (const int &u : g[node]) { if (u == par || depth[u] <= allowedTo) { continue; } addMinMax(u, node, dist + 1, allowedTo); } } void calcMinMax(int node, int par, int dist, int allowedTo) { min = std::min(min, minCNT[color[node]] + dist); max = std::max(max, maxCNT[color[node]] + dist); for (const int &u : g[node]) { if (u == par || depth[u] <= allowedTo) { continue; } calcMinMax(u, node, dist + 1, allowedTo); } } void calcAnswer(int node) { for (const int &u : c[node]) { calcAnswer(u); clearMinMax(u); } for (const int &u : g[node]) { if (depth[u] > depth[node]) { calcMinMax(u, node, 1, depth[node]); addMinMax(u, node, 1, depth[node]); } } max = std::max(max, maxCNT[color[node]]); min = std::min(min, minCNT[color[node]]); } void solve() { if (colorCnt == n) { std::cout << -1 << ' ' << -1 << '\n'; return; } int root = decompose(1, 1); // std::cout << "decomposition\n"; // for (int i = 1 ; i <= n ; ++i) // { // for (const int &u : c[i]) // { // std::cout << i << ' ' << u << '\n'; // } // } std::fill(minCNT + 1, minCNT + 1 + colorCnt, INTINF); std::fill(maxCNT + 1, maxCNT + 1 + colorCnt, -INTINF); calcAnswer(root); std::cout << min << ' ' << max << '\n'; } void input() { std::cin >> n; for (int i = 2 ; i <= n ; ++i) { int u, v; std::cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } for (int i = 1 ; i <= n ; ++i) { std::cin >> color[i]; if (!compr.count(color[i])) { compr[color[i]] = ++colorCnt; } color[i] = compr[color[i]]; } } void fastIOI() { freopen("colors.in", "r", stdin); freopen("colors.out", "w", stdout); std::ios_base :: sync_with_stdio(0); std::cout.tie(nullptr); std::cin.tie(nullptr); } int main() { fastIOI(); input(); solve(); return 0; }