用邻接表构建含两棵树(不连通)的无向图,然后dfs对双根组进行搜索即可
因为是无向图,用List[HTML_REMOVED]表示双根二元组,加上hashSet来表示是否访问
list的equals方法和hashcode都是用值定义的,可以这么做,
若是用地址定义这两个方法的类,就不行。此外,若自己定义双根组,要overdrive这两个方法,否则集合标记无效
代码:
import java.io.*;
import java.math.*;
import java.util.*;
public class Main {
static int N=4*200010;
static int[] h=new int[N],
e=new int[N],
ne=new int[N],
w=new int[N];
static int idx=0;
static void add(int x,int y) {
e[idx]=y;
ne[idx]=h[x];
h[x]=idx;
idx++;
}
static HashSet<List<Integer>> vis=new HashSet<>();
static int dfs(int u1,int u2) {
int res=0;
vis.add(Arrays.asList(u1,u2));
if(w[u1]==w[u2]) {
res++;
int tmp=0;//子对能带来的收益
for(int i=h[u1];i!=-1;i=ne[i]) {
int t1=e[i];
for(int j=h[u2];j!=-1;j=ne[j]) {
int t2=e[j];
if(vis.contains(Arrays.asList(t1,t2))) continue;
if(w[t1]==w[t2]) {//如果这对子节点权值相等,以他们为双根往下递归
tmp=Math.max(tmp,dfs(t1,t2));
}
}
}
res+=tmp;
}
return res;
}
public static void main(String[] args) {
Arrays.fill(h, -1);
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
int m=scanner.nextInt();
int cnt=0;
for(int i=1;i<=n;i++) {
w[i]=scanner.nextInt();
cnt=i;
}
for(int i=1;i<=m;i++) {
w[cnt+i]=scanner.nextInt();
}
for(int i=0;i<n-1;i++) {
int x=scanner.nextInt(),
y=scanner.nextInt();
add(x,y);
add(y,x);
}
for(int i=0;i<m-1;i++) {
int x=scanner.nextInt(),
y=scanner.nextInt();
add(x+cnt,y+cnt);
add(y+cnt,x+cnt);
}
System.out.println(dfs(1,1+cnt));
return;
}
}