[luogu 5024] 保衛王國
阿新 • • 發佈:2018-11-22
luogu 5024(保衛王國)
Problem Here
Solution
這大概是一篇重複累贅的blog吧。
最小覆蓋集=全集-最大獨立集
強制取或不取,可以通過將權值修改成inf或者-inf
然後就用動態dp的套路就行了
#include<bits/stdc++.h> #define ll long long #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*f; } #define MN 100005 #define inf 1000000005 int n,m,v[MN]; struct edge{int to,nex;}e[MN<<1]; int hr[MN],en; std::set<int> mp[MN]; inline void ins(int f,int t) { mp[f].insert(t); mp[t].insert(f); e[++en]=(edge){t,hr[f]};hr[f]=en; e[++en]=(edge){f,hr[t]};hr[t]=en; } int mx[MN],siz[MN],top[MN],fa[MN]; void dfs1(int x,int f) { siz[x]=1;fa[x]=f;register int i; for(i=hr[x];i;i=e[i].nex)if(f^e[i].to) { dfs1(e[i].to,x);siz[x]+=siz[e[i].to]; if(siz[e[i].to]>siz[mx[x]]) mx[x]=e[i].to; } } void dfs2(int x,int f,int tp) { top[x]=tp;if(mx[x]) dfs2(mx[x],x,tp); register int i; for(i=hr[x];i;i=e[i].nex)if((e[i].to^f)&&(e[i].to^mx[x])) dfs2(e[i].to,x,e[i].to); } struct matrix { ll a[2][2]; matrix(){memset(a,0,sizeof a);} matrix operator * (const matrix &b) const { register matrix c;register int i,j,k; for(i=0;i<2;++i)for(j=0;j<2;j++)for(k=0;k<2;++k) c.a[i][j]=max(c.a[i][j],b.a[i][k]+a[k][j]); return c; } }t[MN<<2],Ans; ll g[MN][2],f[MN][2],sum; int pos[MN],id[MN],dind,st[MN]; void init(int x,int F) { register int i;g[x][1]=(ll)v[x]; for(i=hr[x];i;i=e[i].nex) if((e[i].to^F)&&(e[i].to^mx[x])) { init(e[i].to,x); g[x][0]+=max(f[e[i].to][0],f[e[i].to][1]); g[x][1]+=f[e[i].to][0]; } f[x][0]=g[x][0];f[x][1]=g[x][1]; if(mx[x]) { init(mx[x],x); f[x][0]+=max(f[mx[x]][0],f[mx[x]][1]); f[x][1]+=f[mx[x]][0]; } pos[x]=++dind;id[dind]=x; if(st[top[x]]==0) st[top[x]]=dind; } #define mid ((l+r)>>1) void build(int k,int l,int r) { if(l==r) { t[k].a[0][0]=t[k].a[0][1]=g[id[l]][0]; t[k].a[1][0]=g[id[l]][1];t[k].a[1][1]=0ll; return; } build(k<<1,l,mid);build(k<<1|1,mid+1,r); t[k]=t[k<<1]*t[k<<1|1]; } void Modify(int k,int l,int r,int x) { if(l==r) { t[k].a[0][0]=t[k].a[0][1]=g[id[l]][0]; t[k].a[1][0]=g[id[l]][1];t[k].a[1][1]=0ll; return; } if(x<=mid) Modify(k<<1,l,mid,x); else Modify(k<<1|1,mid+1,r,x); t[k]=t[k<<1]*t[k<<1|1]; } matrix query(int k,int l,int r,int a,int b) { if(l==a&&r==b) return t[k]; if(b<=mid) return query(k<<1,l,mid,a,b); if(a>mid) return query(k<<1|1,mid+1,r,a,b); return query(k<<1,l,mid,a,mid)*query(k<<1|1,mid+1,r,mid+1,b); } ll Que() { Ans=query(1,1,n,st[1],pos[1]); return max(Ans.a[0][0],Ans.a[1][0]); } inline void change(int x,ll add) { g[x][1]+=add; while(x!=0){ Modify(1,1,n,pos[x]); matrix tmp=query(1,1,n,st[top[x]],pos[top[x]]); ll f0=tmp.a[0][0],f1=tmp.a[1][0]; if(top[x]!=1){ g[fa[top[x]]][1]+=f0-f[top[x]][0]; g[fa[top[x]]][0]+=max(f1,f0)-max(f[top[x]][0],f[top[x]][1]); } f[top[x]][0]=f0;f[top[x]][1]=f1; x=fa[top[x]]; } } int main() { register char ch[5]; n=read(),m=read();scanf("%s",ch+1); register int i,j,a,b; for(i=1;i<=n;i++) v[i]=read(),sum+=1ll*v[i]; for(i=1;i<n;i++) j=read(),ins(j,read()); dfs1(1,0);dfs2(1,0,1);init(1,0);build(1,1,n); while(m--) { i=read();j=read();a=read(),b=read(); if(j==0&&b==0&&mp[i].count(a)) { puts("-1"); continue; } change(i,(j==0?1:-1)*inf); change(a,(b==0?1:-1)*inf); printf("%lld\n",sum-Que()+1ll*(j==0?1:0)*inf+1ll*(b==0?1:0)*inf); change(i,(j==0?-1:1)*inf); change(a,(b==0?-1:1)*inf); } return 0; }
Blog來自PaperCloud,未經允許,請勿轉載,TKS!