最小支配集=全集-最大独立集
所以先把点权改成正无穷/负无穷来保证强制选/不选某个点到独立集里,然后变成了洛谷的动态DP模板
GTMDNOIP2018ZTY
1 #include<stack> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=100005,M=200005,inf=1e9; 7 int siz[N],far[N],imp[N],top[N],lst[N]; 8 int p[N],noww[M],goal[M],val[N],dfn[N]; 9 int n,m,t1,t2,t3,t4,t5,t6,cnt,tot; 10 char typ[5]; long long sum; 11 struct a 12 { 13 long long mat[2][2]; 14 void Clean() 15 { 16 memset(mat,0,sizeof mat); 17 } 18 }seg[4*N],tre[N]; 19 a Matime(a x,a y) 20 { 21 a ret; ret.Clean(); 22 for(int i=0;i<2;i++) 23 for(int j=0;j<2;j++) 24 for(int k=0;k<2;k++) 25 ret.mat[i][j]=max(ret.mat[i][j],x.mat[i][k]+y.mat[k][j]); 26 return ret; 27 } 28 void Link(int f,int t) 29 { 30 noww[++cnt]=p[f]; 31 goal[cnt]=t,p[f]=cnt; 32 noww[++cnt]=p[t]; 33 goal[cnt]=f,p[t]=cnt; 34 } 35 void DFS(int nde,int fth) 36 { 37 int tmp=0; 38 siz[nde]=1,far[nde]=fth; 39 for(int i=p[nde];i;i=noww[i]) 40 if(goal[i]!=fth) 41 { 42 DFS(goal[i],nde); 43 siz[nde]+=siz[goal[i]]; 44 if(siz[goal[i]]>tmp) 45 tmp=siz[goal[i]],imp[nde]=goal[i]; 46 } 47 } 48 void Mark(int nde,int tpp) 49 { 50 dfn[nde]=++tot,top[nde]=tpp; 51 if(imp[nde]) 52 { 53 Mark(imp[nde],tpp); 54 for(int i=p[nde];i;i=noww[i]) 55 if(goal[i]!=imp[nde]&&goal[i]!=far[nde]) 56 Mark(goal[i],goal[i]); 57 } 58 lst[nde]=imp[nde]?lst[imp[nde]]:nde; 59 } 60 a Query(int nde,int l,int r,int ll,int rr) 61 { 62 if(l>=ll&&r<=rr) 63 return seg[nde]; 64 else 65 { 66 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; 67 if(mid>=ll&&mid<rr) 68 return Matime(Query(rs,mid+1,r,ll,rr),Query(ls,l,mid,ll,rr)); 69 if(mid>=rr) return Query(ls,l,mid,ll,rr); 70 if(mid<ll) return Query(rs,mid+1,r,ll,rr); 71 } 72 } 73 void Modify(int nde,int l,int r,int pos,a tsk) 74 { 75 if(l==r) seg[nde]=tsk; 76 else 77 { 78 int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; 79 if(pos<=mid) Modify(ls,l,mid,pos,tsk); 80 else Modify(rs,mid+1,r,pos,tsk); 81 seg[nde]=Matime(seg[rs],seg[ls]); 82 } 83 } 84 void Prework(int nde) 85 { 86 stack<int> st; 87 for(int i=nde;i;i=imp[i]) st.push(i); 88 while(!st.empty()) 89 { 90 int tn=st.top(); st.pop(); 91 long long x=0,y=val[tn]; 92 for(int i=p[tn];i;i=noww[i]) 93 if(goal[i]!=imp[tn]&&goal[i]!=far[tn]) 94 { 95 Prework(goal[i]); a mtr=tre[goal[i]]; 96 x+=max(mtr.mat[0][0],mtr.mat[0][1]),y+=mtr.mat[0][0]; 97 } 98 a tmp; tmp.mat[0][0]=tmp.mat[1][0]=x,tmp.mat[0][1]=y,tmp.mat[1][1]=-inf; 99 Modify(1,1,n,dfn[tn],tmp); 100 } 101 tre[nde]=Query(1,1,n,dfn[nde],dfn[lst[nde]]); 102 } 103 void Change(int nde,long long tsk) 104 { 105 a tmp=Query(1,1,n,dfn[nde],dfn[nde]); 106 tmp.mat[0][1]+=tsk-val[nde]; 107 Modify(1,1,n,dfn[nde],tmp),val[nde]=tsk; 108 for(int i=top[nde];i!=1;i=top[i]) 109 { 110 int fa=far[i]; 111 a tmp=Query(1,1,n,dfn[fa],dfn[fa]),tep=Query(1,1,n,dfn[i],dfn[lst[i]]); 112 tmp.mat[0][0]+=max(tep.mat[0][0],tep.mat[0][1])-max(tre[i].mat[0][0],tre[i].mat[0][1]); 113 tmp.mat[0][1]+=tep.mat[0][0]-tre[i].mat[0][0],tmp.mat[1][0]=tmp.mat[0][0]; 114 Modify(1,1,n,dfn[fa],tmp),tre[i]=tep,i=fa; 115 } 116 } 117 int main() 118 { 119 scanf("%d%d%s",&n,&m,typ); 120 for(int i=1;i<=n;i++) 121 scanf("%d",&val[i]),sum+=val[i]; 122 for(int i=1;i<n;i++) 123 scanf("%d%d",&t1,&t2),Link(t1,t2); 124 DFS(1,0),Mark(1,1),Prework(1); 125 while(m--) 126 { 127 scanf("%d%d%d%d",&t1,&t2,&t3,&t4); 128 if(!t2&&!t4&&(far[t1]==t3||far[t3]==t1)) 129 printf("-1 "); 130 else 131 { 132 t5=val[t1],t6=val[t3]; 133 Change(t1,t2?-inf:inf); 134 Change(t3,t4?-inf:inf); 135 a qry=Query(1,1,n,1,dfn[lst[1]]); 136 long long ans=sum-max(qry.mat[0][0],qry.mat[0][1]); 137 printf("%lld ",ans+(inf-t5)*(t2^1)+(inf-t6)*(t4^1)); 138 Change(t1,t5),Change(t3,t6); 139 } 140 } 141 return 0; 142 }