我来了!!!
2023-08-16 09:52:36
发布于:广东
5阅读
0回复
0点赞
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#define INF 214748364700
#define ll long long
using namespace std;
const ll two[18]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072};
ll tot,head[100010],ver[200010],Next[200010];
ll n,m,a[100010],p[19][100010],dep[100010],Log[100010];
ll dp[3][100010],f[3][3][19][100010];
inline void addEdge(ll x,ll y){
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
void dfs(ll x){
dep[x]=dep[p[0][x]]+1;
dp[1][x]=a[x];
f[0][0][0][x]=INF;
for(ll i=1; (1<<(i-1))<dep[x]; i++) p[i][x]=p[i-1][p[i-1][x]];
for(ll i=head[x]; i; i=Next[i]){
ll y=ver[i];
if(y!=p[0][x]){
p[0][y]=x;
dfs(y);
dp[0][x]+=dp[1][y];
dp[1][x]+=min(dp[0][y],dp[1][y]);
}
}
}
void get_LCA(ll x){
f[1][0][0][x]=dp[0][p[0][x]]-dp[1][x],
f[0][1][0][x]=f[1][1][0][x]=dp[1][p[0][x]]-min(dp[0][x],dp[1][x]);
for(ll i=1; two[i]<dep[x]; i++){
ll y=p[i-1][x];
f[0][0][i][x]=min(f[0][0][i-1][x]+f[0][0][i-1][y],f[0][1][i-1][x]+f[1][0][i-1][y]),
f[0][1][i][x]=min(f[0][0][i-1][x]+f[0][1][i-1][y],f[0][1][i-1][x]+f[1][1][i-1][y]),
f[1][0][i][x]=min(f[1][0][i-1][x]+f[0][0][i-1][y],f[1][1][i-1][x]+f[1][0][i-1][y]),
f[1][1][i][x]=min(f[1][0][i-1][x]+f[0][1][i-1][y],f[1][1][i-1][x]+f[1][1][i-1][y]);
}
for(ll i=head[x]; i; i=Next[i]){
if(ver[i]!=p[0][x]) get_LCA(ver[i]);
}
}
inline void LCA(ll u,ll x,ll v,ll y){
if(dep[u]<dep[v]){
swap(u,v);
swap(x,y);
}
ll L,u0=INF,u1=INF,v0=INF,v1=INF,l0=INF,l1=INF,ans;
x?u1=dp[1][u]:u0=dp[0][u];
y?v1=dp[1][v]:v0=dp[0][v];
for(ll i=Log[dep[u]-dep[v]]; i>=0; i--){
if(dep[u]-two[i]>=dep[v]){
ll t0=u0,t1=u1;
u0=min(t0+f[0][0][i][u],t1+f[1][0][i][u]);
u1=min(t0+f[0][1][i][u],t1+f[1][1][i][u]);
u=p[i][u];
}
}
if(u==v){
L=u;
y?l1=u1:l0=u0;
}
else{
for(ll i=Log[dep[u]-1]; i>=0; i--){
if(p[i][u]!=p[i][v]){
ll t0=u0,t1=u1,p0=v0,p1=v1;
u0=min(t0+f[0][0][i][u],t1+f[1][0][i][u]);
u1=min(t0+f[0][1][i][u],t1+f[1][1][i][u]);
v0=min(p0+f[0][0][i][v],p1+f[1][0][i][v]);
v1=min(p0+f[0][1][i][v],p1+f[1][1][i][v]);
u=p[i][u]; v=p[i][v];
}
}
L=p[0][u];
l0=dp[0][L]-dp[1][u]-dp[1][v]+u1+v1;
l1=dp[1][L]-min(dp[0][u],dp[1][u])-min(dp[0][v],dp[1][v])+min(u0,u1)+min(v0,v1);
}
if(L==1) ans=min(l0,l1);
else{
for(ll i=Log[dep[L]-2]; i>=0; i--){
if(dep[L]-two[i]>1){
ll t0=l0,t1=l1;
l0=min(t0+f[0][0][i][L],t1+f[1][0][i][L]);
l1=min(t0+f[0][1][i][L],t1+f[1][1][i][L]);
L=p[i][L];
}
}
ans=min(dp[0][1]-dp[1][L]+l1,dp[1][1]-min(dp[0][L],dp[1][L])+min(l0,l1));
}
printf("%lld\n",ans<INF?ans:-1);
}
int main(){
scanf("%lld %lld %*s",&n,&m);
for(ll i=1; i<=n; i++) scanf("%lld",&a[i]);
for(ll i=1; i<n; i++){
ll x,y;
scanf("%lld %lld",&x,&y);
addEdge(x,y);
addEdge(y,x);
Log[i]=Log[i/2]+1;
}
dfs(1);
get_LCA(1);
while(m--){
ll u,x,v,y;
scanf("%lld %lld %lld %lld",&u,&x,&v,&y);
LCA(u,x,v,y);
}
return 0;
}
这里空空如也
有帮助,赞一个