AT_arc097_d [ARC097F] Monochrome Cat
Solution
一道模拟赛的 T3,好不容易做出来结果 T1 爆 0 了。
令 \(\texttt{W}\) 的值为 \(1\),\(\texttt{B}\) 的值为 \(0\)。转化为将所有的点变为 \(0\)。
考虑起点和终点在同一个点的情况,肯定需要将所有为 \(w_i=1\) 的点都遍历一遍。先去掉所有点均为 \(0\) 的子树,若要进去答案肯定不优。此时会形成一个叶子均为 \(1\) 的新树。
会有每个点被进入的次数为它的度数。设 \(E\) 为新树的边集,第 \(i\) 个点的度数为 \(d_i\)。此时的答案为 \(|E|\times 2+\sum w_i\oplus (d_i \& 1)\)。即如果 \(i\) 被进入奇数次,那它的权值就会改变。
将 \(w_i\) 更改为 \(w_i\oplus (d_i\&1)\)。
若起点和终点不相同,那么会有从起点到终点的路径除了终点以外的点的权值均会改变。设路径长为 \(L\),除了终点的点集为 \(V\),有 \(L=|V|\)。那么答案会减少 \(L+\sum\limits_{i\in V} [w_i=1]-\sum\limits_{i\in V} [w_i=0]=\sum\limits_{i\in V} [w_i=1]\times (1+1)-\sum\limits_{i\in V} [w_i=0]\times (1-1)=2\times\sum\limits_{i\in V} [w_i=1]\)。
因此需要求 \(\sum\limits_{i\in V} [w_i=1]\) 最大的路径。
会发现端点的值一定为 \(0\),因此不用考虑终点的值。设 \(h_i\) 表示 \(i\) 到子树的最大的权值, \(g_i\) 表示经过 \(i\) 的链的权值最大值。树形 dp 即可。
注意: 要特判只有一个点为 \(1\) 的情况,此时答案为 \(1\),不判可能会输出 \(-1\)。
Code
#include<bits/stdc++.h>
#define IOS cin.tie(0),cout.tie(0),ios::sync_with_stdio(0)
#define ll long long
#define db double
#define pb push_back
#define eb emplace_back
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define PLL pair<ll,ll>
#define PII pair<int,int>
#define Tp template<typename T>
#define Ts template<typename T,typename ...args>
Tp inline T lb(T x){return x&-x;}
using namespace std;
const int N=1e5+20,M=1e5+20;
const ll INF=1ll<<60,mod=998244353;
namespace H_H{
int n,rt=1,f[N],sum_w,E;
vector<int> to[N],to1[N];
bool w[N],in[N];
inline void dfs1(int u,int fa){
if(w[u]) f[u]=1;
for(int v:to[u]){
if(v==fa) continue;
dfs1(v,u);
f[u]+=f[v];
}
in[u]=f[u] && (sum_w-f[u] || w[u]);
}
inline void solve1(){//求新树
dfs1(rt,0);
for(int i=1;i<=n;i++){
if(!in[i]) continue;
for(int v:to[i]) if(in[v]) to1[i].pb(v),E++;
}
swap(to,to1);
sum_w=0;
for(int i=1;i<=n;i++){
if(!in[i]) continue;
w[i]^=(int)to[i].size()&1;
sum_w+=w[i];
}
}
int g[N],h[N];
inline void dfs2(int u,int fa){//树形 dp
int mx1=0,mx2=0;//维护最大和次大值
for(int v:to[u]){
if(v==fa) continue;
dfs2(v,u);
h[u]=max(h[u],h[v]);
if(h[v]>mx1) mx2=mx1,mx1=h[v];
else mx2=max(mx2,h[v]);
}
h[u]+=w[u];g[u]=mx1+mx2+w[u];
}
inline ll calc(){
dfs2(rt,0);
int ans=0;
for(int i=1;i<=n;i++){
if(in[i]) ans=max(ans,g[i]);
}
if(E+sum_w==1) return 1;
return E+sum_w-ans*2;
}
int main(){
cin>>n;
for(int i=1,u,v;i<n;i++){
cin>>u>>v;
to[u].pb(v);
to[v].pb(u);
}
for(int i=1;i<=n;i++){
char ch;cin>>ch;
sum_w+=(w[i]=ch=='W');
if(w[i]) rt=i;
}
solve1();
cout<<calc()<<"\n";
return 0;
}
}
int main(){
IOS;H_H::main();
return 0;
}

浙公网安备 33010602011771号