#include //#include #include #include #include #include #include using namespace std; typedef int var; #define fin cin #define fout cout //ifstream fin("date.in"); //ofstream fout("date.out"); #define MAXN 20002 #define MAXNLOGN 20 var n, m; vector G[MAXN]; var SPEC[MAXN], SERV[MAXN]; vector EULER(1), DEPTH(1); var BEG[MAXN], D[MAXN], LOG[MAXN]; var RMQ[MAXNLOGN][MAXN], SOL[MAXNLOGN][MAXN]; struct Edge { var n, c; Edge(var a, var b) { n = a; c = b; } }; vector Gr[MAXN]; void euler(var node) { BEG[node] = EULER.size(); EULER.push_back(node); DEPTH.push_back(D[node]); for(auto vec : G[node]) { if(!BEG[vec]) { D[vec] = D[node] + 1; euler(vec); EULER.push_back(node); DEPTH.push_back(D[node]); } } } void build_log_table(var maxx) { for(var i=2; i<=maxx; i++) { LOG[i] = LOG[i/2] + 1; } } void build_lookup_table(var maxx) { for(var i=1; i<=maxx; i++) { RMQ[0][i] = DEPTH[i]; SOL[0][i] = EULER[i]; } for(var i=1; (1< b) swap(a, b); var len = LOG[b-a+1]; if(RMQ[len][a] < RMQ[len][b-(1< cost) continue; if(!R[vec]) { R[vec] = i; L[i] = vec; return true; } } for(int t=0; t cost) continue; if(pairup(R[vec], cost)) { R[vec] = i; L[i] = vec; return true; } } return false; } bool solve(var cost) { bool ok = 1; memset(L, 0, sizeof(L)); memset(R, 0, sizeof(R)); while(ok) { ok = 0; memset(VIZ, false, sizeof(VIZ)); for(int i=1; i<=n; i++) { if(!L[i]) ok |= pairup(i, cost); } } for(var i=1; i<=m; i++) { if(!R[i]) return false; } return true; } var maxD = -1; int main() { var a, b; fin>>n>>m; for(var i=1; i<=m; i++) { fin>>SPEC[i]; } for(var i=1; i<=m; i++) { fin>>SERV[i]; } for(var i=2; i<=n; i++) { fin>>a>>b; G[a].push_back(b); G[b].push_back(a); } euler(1); build_log_table(3*n+5); build_lookup_table(EULER.size() - 1); for(var i=1; i<=m; i++) { for(var j=1; j<=m; j++) { var d = getD(SPEC[i], SERV[j]); maxD = max(maxD, d); Gr[i].push_back(Edge(j, d)); } } var sol = 0; var i; for(i=1; i<=n; i<<=1); for(i>>=1; i; i>>=1) { if(!solve(sol+i)) sol += i; } while(!solve(sol)) { sol++; } fout<