我直接求最小覆盖集 为什么不能把DP直接赋成inf
而是加上inf 我不理解
#include<bits/stdc++.h>
#define int long long
#define mid ((l+r)>>1)
#define ls (now<<1)
#define rs ((now<<1)|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
int n,m;
const int maxn=1e5+5;
int a[maxn];
basic_string<int>e[maxn];
string s;
void RD(){
n=read(),m=read(),cin>>s;
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<n;i++){
int u,v;
u=read(),v=read();
e[u]+=v;
e[v]+=u;
}
}
int son[maxn],siz[maxn],dep[maxn],top[maxn],id[maxn],dfn[maxn],End[maxn],tt=0;
int Fa[maxn],f[maxn][2];
struct mat{
int g[2][2];
mat(){
memset(g,0,sizeof(g));
}
void init(){
for(int i=0;i<=1;i++) for(int j=0;j<=1;j++) g[i][j]=1e10;
return ;
}
};
mat G[maxn];
mat operator *(mat a,mat b){
mat ret;ret.init();
for(int i=0;i<=1;i++) for(int j=0;j<=1;j++) for(int k=0;k<=1;k++) ret.g[i][j]=min(ret.g[i][j],a.g[i][k]+b.g[k][j]);
return ret;
}
void dfs1(int x,int fa){
dep[x]=dep[fa]+1;
siz[x]=1;
f[x][1]=a[x];
Fa[x]=fa;
int mx=0;
for(auto y:e[x]){
if(y==fa ) continue;
dfs1(y,x);
siz[x]+=siz[y];
if(mx<siz[y]){
mx=siz[y],son[x]=y;
}
f[x][1]+=min(f[y][0],f[y][1]);
f[x][0]+=f[y][1];
}
return ;
}
void dfs2(int x,int fa){
G[x].g[0][0]=1e10;
G[x].g[1][0]=a[x];
dfn[++tt]=x,id[x]=tt;
End[top[x]]=x;
if(son[x]){
top[son[x]]=top[x];
dfs2(son[x],x);
}
for(auto y:e[x]){
if(y==fa||y==son[x]) continue;
top[y]=y;
dfs2(y,x);
G[x].g[0][1]+=f[y][1];
G[x].g[1][0]+=min(f[y][0],f[y][1]);
}
G[x].g[1][1]=G[x].g[1][0];
return ;
}
mat tr[maxn*4];
void up(int now,int l,int r){
tr[now]=tr[ls]*tr[rs];
}
void build(int now,int l,int r){
if(l==r){
tr[now]=G[dfn[l]];
return ;
}
build(lson),build(rson);
up(now,l,r);
}
inline mat query(int now,int l,int r,int L,int R){
if(L<=l&&r<=R){
return tr[now];
}
if(R<=mid) return query(lson,L,R);
if(L>=mid+1) return query(rson,L,R);
return query(lson,L,R)*query(rson,L,R);
}
void add(int now,int l,int r,int pos){
if(l==r){
tr[now]=G[dfn[pos]];
return ;
}
if(pos<=mid) add(lson,pos);
if(pos>=mid+1) add(rson,pos);
up(now,l,r);
}
void POU(){
dfs1(1,1);
top[1]=1;
dfs2(1,1);
}
void SHU(){
build(1,1,n);
}
mat Tp;
void update(int a,int x,int op){
if(a==0){
G[x].g[1][0]+=op*1e10;
G[x].g[1][1]=G[x].g[1][0];
}
else if(a==1){
G[x].g[0][1]+=op*1e10;
}
Fa[1]=0;
while(x){
mat lst=query(1,1,n,id[top[x]],id[End[top[x]]]);
add(1,1,n,id[x]);
mat now=query(1,1,n,id[top[x]],id[End[top[x]]]);
x=Fa[top[x]];
int f00=min(lst.g[0][1],lst.g[0][0]),f01=min(now.g[0][1],now.g[0][0]);
int f10=min(lst.g[1][0],lst.g[1][1]),f11=min(now.g[1][0],now.g[1][1]);
G[x].g[0][1]+=f11-f10;
G[x].g[1][0]+=min(f01,f11)-min(f00,f10);
G[x].g[1][1]=G[x].g[1][0];
}
return ;
}
void WORK(){
while(m--){
int a,x,b,y;
x=read(),a=read(),y=read(),b=read();
// mat now1=G[x],now2=G[y];
update(a,x,1);
update(b,y,1);
mat ret=query(1,1,n,id[1],id[End[1]]);
int ans=min(min(ret.g[0][1],ret.g[0][0]),min(ret.g[1][0],ret.g[1][1]));
if(ans>=1e10){
cout<<-1<<endl;
}
else cout<<ans<<endl;
update(a,x,-1);
update(b,y,-1);
ret=query(1,1,n,id[1],id[End[1]]);
}
return ;
}
signed main(){
RD();
POU();
SHU();
WORK();
return 0;
}
#include<bits/stdc++.h>
#define int long long
#define mid ((l+r)>>1)
#define ls (now<<1)
#define rs ((now<<1)|1)
#define lson ls,l,mid
#define rson rs,mid+1,r
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
int n,m;
const int maxn=1e5+5;
int a[maxn];
basic_string<int>e[maxn];
string s;
void RD(){
n=read(),m=read(),cin>>s;
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<n;i++){
int u,v;
u=read(),v=read();
e[u]+=v;
e[v]+=u;
}
}
int son[maxn],siz[maxn],dep[maxn],top[maxn],id[maxn],dfn[maxn],End[maxn],tt=0;
int Fa[maxn],f[maxn][2];
struct mat{
int g[2][2];
mat(){
memset(g,0,sizeof(g));
}
void init(){
for(int i=0;i<=1;i++) for(int j=0;j<=1;j++) g[i][j]=1e10;
return ;
}
};
mat G[maxn];
mat operator *(mat a,mat b){
mat ret;ret.init();
for(int i=0;i<=1;i++) for(int j=0;j<=1;j++) for(int k=0;k<=1;k++) ret.g[i][j]=min(ret.g[i][j],a.g[i][k]+b.g[k][j]);
return ret;
}
void dfs1(int x,int fa){
dep[x]=dep[fa]+1;
siz[x]=1;
f[x][1]=a[x];
Fa[x]=fa;
int mx=0;
for(auto y:e[x]){
if(y==fa ) continue;
dfs1(y,x);
siz[x]+=siz[y];
if(mx<siz[y]){
mx=siz[y],son[x]=y;
}
f[x][1]+=min(f[y][0],f[y][1]);
f[x][0]+=f[y][1];
}
return ;
}
void dfs2(int x,int fa){
G[x].g[0][0]=1e10;
G[x].g[1][0]=a[x];
dfn[++tt]=x,id[x]=tt;
End[top[x]]=x;
if(son[x]){
top[son[x]]=top[x];
dfs2(son[x],x);
}
for(auto y:e[x]){
if(y==fa||y==son[x]) continue;
top[y]=y;
dfs2(y,x);
G[x].g[0][1]+=f[y][1];
G[x].g[1][0]+=min(f[y][0],f[y][1]);
}
G[x].g[1][1]=G[x].g[1][0];
return ;
}
mat tr[maxn*4];
void up(int now,int l,int r){
tr[now]=tr[ls]*tr[rs];
}
void build(int now,int l,int r){
if(l==r){
tr[now]=G[dfn[l]];
return ;
}
build(lson),build(rson);
up(now,l,r);
}
inline mat query(int now,int l,int r,int L,int R){
if(L<=l&&r<=R){
return tr[now];
}
if(R<=mid) return query(lson,L,R);
if(L>=mid+1) return query(rson,L,R);
return query(lson,L,R)*query(rson,L,R);
}
void add(int now,int l,int r,int pos){
if(l==r){
tr[now]=G[dfn[pos]];
return ;
}
if(pos<=mid) add(lson,pos);
if(pos>=mid+1) add(rson,pos);
up(now,l,r);
}
void POU(){
dfs1(1,1);
top[1]=1;
dfs2(1,1);
}
void SHU(){
build(1,1,n);
}
mat Tp;
void update(int a,int x){
if(a==0){
G[x].g[1][0]=1e10;
G[x].g[1][1]=1e10;
}
else if(a==1){
G[x].g[0][1]=1e10;
}
else if(a==2){
G[x]=Tp;
}
Fa[1]=0;
while(x){
mat lst=query(1,1,n,id[top[x]],id[End[top[x]]]);
add(1,1,n,id[x]);
mat now=query(1,1,n,id[top[x]],id[End[top[x]]]);
x=Fa[top[x]];
int f00=min(lst.g[0][1],lst.g[0][0]),f01=min(now.g[0][1],now.g[0][0]);
int f10=min(lst.g[1][0],lst.g[1][1]),f11=min(now.g[1][0],now.g[1][1]);
G[x].g[0][1]+=f11-f10;
G[x].g[1][0]+=min(f01,f11)-min(f00,f10);
G[x].g[1][1]=G[x].g[1][0];
}
return ;
}
void WORK(){
while(m--){
int a,x,b,y;
x=read(),a=read(),y=read(),b=read();
mat now1=G[x],now2=G[y];
update(a,x);
update(b,y);
mat ret=query(1,1,n,id[1],id[End[1]]);
int ans=min(min(ret.g[0][1],ret.g[0][0]),min(ret.g[1][0],ret.g[1][1]));
if(ans>=1e10){
cout<<-1<<endl;
}
else cout<<ans<<endl;
Tp=now1;update(2,x);
Tp=now2;update(2,y);
ret=query(1,1,n,id[1],id[End[1]]);
}
return ;
}
signed main(){
RD();
POU();
SHU();
WORK();
return 0;
}