[luogu 5024] 保卫王国

Problem Here

Solution


这大概是一篇重复累赘的blog吧。

最小权覆盖集=全集-最大权独立集

强制取或不取,可以通过将权值修改成inf或者-inf

然后就用动态dp的套路就行了

动态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
",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!

原文地址:https://www.cnblogs.com/PaperCloud/p/10000428.html