标签:+= line std col its ref 表示 stat 最大
\[ \texttt{Description} \]
给定一棵 \(n\) 个点的树,每个点有一个颜色( "黑" 或 "白" )。
对于每个点 \(x\) ,求出所有包含点 \(x\) 的联通子图中,白点数减去黑点数的最大值是多少。
\[
\texttt{Solution}
\]
\[ f_u = \begin{cases} \sum\limits_{v \in \text{son(u)}}\max(f_v,0)-1 & col_x = \texttt{black} \\ \sum\limits_{v \in \text{son(u)}}\max(f_v,0)+1 & col_u = \texttt{white} \end{cases} \]
\[ g_u = \begin{cases} f_u & u=\texttt{root} \\ f_u +\max(g_{fa}-\max(f_u,0),0) & u \neq \texttt{root} \end{cases} \]
\[ \texttt{Code} \]
#include<cstdio>
#include<algorithm>
#include<queue>
#define RI register int
using namespace std;
namespace IO
{
static char buf[1<<20],*fs,*ft;
inline char gc()
{
if(fs==ft)
{
ft=(fs=buf)+fread(buf,1,1<<20,stdin);
if(fs==ft)return EOF;
}
return *fs++;
}
#define gc() getchar()
inline int read()
{
int x=0,f=1;char s=gc();
while(s<'0'||s>'9'){if(s=='-')f=-f;s=gc();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=gc();}
return x*f;
}
}using IO::read;
const int N=200100,M=400100;
int n;
int a[N];
int tot,head[N],ver[M],Next[M];
void add(int u,int v)
{
ver[++tot]=v; Next[tot]=head[u]; head[u]=tot;
}
int f[N];
int g[N];
void calc(int u,int fu)
{
if(a[u]==1)
f[u]++;
else
f[u]--;
for(RI i=head[u];i;i=Next[i])
{
int v=ver[i];
if(v==fu)continue;
calc(v,u);
if(f[v]>0)
f[u]+=f[v];
}
}
bool vis[N];
void bfs()
{
queue<int>q;
q.push(1);
g[1]=f[1];
vis[1]=true;
while(q.size())
{
int u=q.front();q.pop();
for(RI i=head[u];i;i=Next[i])
{
int v=ver[i];
if(vis[v])
continue;
g[v]=f[v]+max(0,g[u]-max(0,f[v]));
vis[v]=true;
q.push(v);
}
}
}
int main()
{
n=read();
for(RI i=1;i<=n;i++)
a[i]=read();
for(RI i=1;i<n;i++)
{
int u=read(),v=read();
add(u,v),add(v,u);
}
calc(1,0);
bfs();
for(RI i=1;i<=n;i++)
printf("%d ",g[i]);
puts("");
return 0;
}
\[ \texttt{Thanks} \ \texttt{for} \ \texttt{watching} \]
题解【CF1324F Maximum White Subtree】
标签:+= line std col its ref 表示 stat 最大
原文地址:https://www.cnblogs.com/cjtcalc/p/12485536.html