rt,在判无解上出了问题。算法是 ddp,但没有利用最小点覆盖=全-最大点独立,直接 dp。强制选,将 gx,0 赋 inf,强制不选,将 gx,1 赋 inf。判无解1:两点在一条边两端且都强制不选,判无解2:答案超过 1010,因为点数 105,点权 105。
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define int long long
#define pii pair<int,int>
const int N=1e5+5;
const LL inf=1e18;
int n,m,df,cnt;
int dep[N],f[N],son[N],siz[N],top[N],dfn[N],idfn[N],ed[N],a[N],g[N][2],dp[N][2],head[N];
string s;
map<pii,int> ap;
struct node{
int to,ne;
}e[N<<1];
inline void dfs(int x,int fa){
dep[x]=dep[fa]+1;
f[x]=fa;
siz[x]=1;
for(int i=head[x];i;i=e[i].ne){
int y=e[i].to;
if(y!=fa){
dfs(y,x);
siz[x]+=siz[y];
if(siz[y]>siz[son[x]]){
son[x]=y;
}
}
}
}
inline void dfs2(int x,int tp){
top[x]=tp;
dfn[x]=++df;
idfn[df]=x;
int sn=0;
for(int i=head[x];i;i=e[i].ne){
int y=e[i].to;
if(y!=f[x]) sn++;
}
if(!sn) ed[tp]=x;
g[x][1]=a[x];
if(son[x]){
dfs2(son[x],tp);
dp[x][1]+=min(dp[son[x]][1],dp[son[x]][0]);
dp[x][0]+=dp[son[x]][1];
}
for(int i=head[x];i;i=e[i].ne){
int y=e[i].to;
if(y!=f[x]&&y!=son[x]){
dfs2(y,y);
g[x][0]+=dp[y][1];
g[x][1]+=min(dp[y][0],dp[y][1]);
}
}
dp[x][0]+=g[x][0];
dp[x][1]+=g[x][1];
}
struct mat{
LL at[2][2];
mat(){at[0][0]=at[0][1]=at[1][0]=at[1][1]=inf;}
void bs(){at[0][0]=at[0][1]=0;at[1][0]=at[1][1]=4e18;}
void prin(){cout<<at[0][0]<<" "<<at[0][1]<<"\n"<<at[1][0]<<" "<<at[1][1]<<"\n";}
};
mat operator*(mat a,mat b){
mat c;
c.at[0][0]=min(a.at[0][0]+b.at[0][0],a.at[0][1]+b.at[1][0]);
c.at[0][1]=min(a.at[0][0]+b.at[0][1],a.at[0][1]+b.at[1][1]);
c.at[1][0]=min(a.at[1][0]+b.at[0][0],a.at[1][1]+b.at[1][0]);
c.at[1][1]=min(a.at[1][0]+b.at[0][1],a.at[1][1]+b.at[1][1]);
return c;
}
struct seg{
mat t[N<<2],pre[N<<2];
inline void pp(int p){t[p]=t[p<<1|1]*t[p<<1];}
inline void build(int p,int l,int r){
if(l==r){
t[p].at[0][1]=g[idfn[l]][1];
t[p].at[1][0]=g[idfn[l]][0];
t[p].at[1][1]=g[idfn[l]][1];
pre[p]=t[p];
return ;
}
int mid=l+r>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
pp(p);
}
inline void md(int p,int l,int r,int x,int k){
if(l==r){
if(k==1){
t[p].at[0][0]=t[p].at[1][0]=inf;
t[p].at[0][1]=t[p].at[1][1]=g[idfn[l]][1];
}
else if(k==0){
t[p].at[0][0]=t[p].at[0][1]=t[p].at[1][1]=inf;
t[p].at[1][0]=g[idfn[l]][0];
}
else{
t[p].at[0][0]=inf;
t[p].at[1][0]=g[idfn[l]][0];
t[p].at[0][1]=t[p].at[1][1]=g[idfn[l]][1];
}
return ;
}
int mid=l+r>>1;
if(x<=mid) md(p<<1,l,mid,x,k);
else md(p<<1|1,mid+1,r,x,k);
pp(p);
}
inline void topre(int p,int l,int r,int x){
if(l==r){
t[p]=pre[p];
g[idfn[l]][0]=pre[p].at[1][0];
g[idfn[l]][1]=pre[p].at[0][1];
return ;
}
int mid=l+r>>1;
if(x<=mid) topre(p<<1,l,mid,x);
else topre(p<<1|1,mid+1,r,x);
pp(p);
}
inline mat query(int p,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr){
return t[p];
}
int mid=l+r>>1;
if(qr<=mid) return query(p<<1,l,mid,ql,qr);
if(ql>mid) return query(p<<1|1,mid+1,r,ql,qr);
return query(p<<1|1,mid+1,r,ql,qr)*query(p<<1,l,mid,ql,qr);
}
}sg;
inline void ct(){
dfs(1,0);
dfs2(1,1);
sg.build(1,1,n);
}
inline mat getdp(int x){
mat bs;bs.bs();
return bs*sg.query(1,1,n,dfn[x],dfn[ed[x]]);
}
inline void mp(int x,int k){
int tm=x;
while(1){
auto as=getdp(top[x]);
g[f[top[x]]][0]-=as.at[0][1];
g[f[top[x]]][1]-=min(as.at[0][1],as.at[0][0]);
sg.md(1,1,n,dfn[x],tm==x?k:-1);
as=getdp(top[x]);
g[f[top[x]]][0]+=as.at[0][1];
g[f[top[x]]][1]+=min(as.at[0][1],as.at[0][0]);
if(top[x]==1) break;
x=f[top[x]];
}
}
inline void pre(int x){
while(1){
sg.topre(1,1,n,dfn[x]);
if(top[x]==1) break;
x=f[top[x]];
}
}
inline void modify(int a,int x,int b,int y){
mp(a,x);
mp(b,y);
auto as=getdp(1);
LL minn=min(as.at[0][1],as.at[0][0]);
if(minn>1e10) cout<<"-1\n";
else cout<<minn<<"\n";
pre(a);
pre(b);
}
inline void add(int x,int y){
e[++cnt]=(node){y,head[x]};
head[x]=cnt;
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n>>m>>s;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1,x,y;i<n;i++){
cin>>x>>y;
add(x,y);
add(y,x);
ap[{x,y}]=ap[{y,x}]=1;
}
ct();
while(m--){
int a,x,b,y;
cin>>a>>x>>b>>y;
if(!x&&!y&&ap[{x,y}]){
cout<<"-1\n";
return 0;
}
modify(a,x,b,y);
}
return 0;
}