题意:给一棵树每个节点刚开始都是白色的,告诉你A+B中约束条件是,某个子树下至少有多少黑,子树之外最少多少黑,
问你最少的黑点,可以满足这A+B种限定条件
解:
1、子树外的下界在已经确定黑点个数的情况下可以转化为 一个子树的上界,
2、二分黑点的个数,就转化为判定,一个树上的上下界是否都可行的问题。
3、上下界的传递就是
下界:儿子的下界求和 传递上来,儿子的上界求和+1(本身)在传递上来,最后判定 mid是否在最后root的上下界里面
#include<bits/stdc++.h>
#define en '\n'
#define ll long long
const ll maxn=1e5+10;
using namespace std;
const int inf=0x3f3f3f3f;
ll a[maxn],k,n;
int rd(){int tem;scanf("%d",&tem);return tem;}
vector<int>vec[maxn];
int A[maxn],B[maxn],xia[maxn],shang[maxn],sz[maxn];
void dfs(int x,int f){
sz[x]=1;
for(auto y:vec[x]){
if(y==f)continue;
dfs(y,x);
sz[x]+=sz[y];
}
}
bool dfs2(int x,int f){
int dd=0,up=1;
for(auto y: vec[x]){
if(y==f)continue;
if(!dfs2(y,x))return 0;
dd+=xia[y];up+=shang[y];
}
xia[x]=max(A[x],dd);
shang[x]=min(shang[x],up);
return xia[x]<=shang[x];
}
bool ok(int x){
for(int i=1;i<=n;i++){
shang[i]=min(x-B[i],sz[i]);
if(shang[i]<0)return 0;
}
return dfs2(1,0) and xia[1]<=x and shang[1]>=x;
}
signed main()
{
#ifdef swt
freopen("input2.txt","r",stdin);
#endif
int T;
cin>>T;
while(T--){
cin>>n;
#define pb push_back
for(int i=1;i<=n;i++)vec[i].clear(),shang[i]=0,xia[i]=0,A[i]=0,B[i]=0;
for(int i=1;i<n;i++){int x=rd(),y=rd();vec[x].pb(y),vec[y].pb(x);}
dfs(1,0);
int m=rd();
bool yes=1;
while(m--){
int x=rd(),y=rd();
A[x]=max(A[x],y);
if(A[x]>sz[x]){
yes=0;
}
}
m=rd();
while(m--){
int x=rd(),y=rd();
B[x]=max(B[x],y);
if(B[x]>n-sz[x]){
yes=0;
}
}
int l=0,r=n;
while(l<r){
int mid=(l+r)>>1;
if(ok(mid)){
r=mid;
}else l=mid+1;
}
if(!yes){cout<<-1<<en;}
else cout<<l<<en;
}
return 0;
}