思路
时,两个good vertex是不可能相邻的,那么good vertex的最大值就是树的最大独立集。考虑已知最大独立集是哪些之后怎么让权值最小。显然普通点全部是,good vertex是它的度数可以保证最小权值和。设为节点是()/不是()good vertex时子树在保证good vertex最多的前提下的最小权值和,在求最大独立集的同时把这个一起算出来就可以了。
代码
#include<bits/stdc++.h>
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
#define bl(u,i) for(int i=head[u];i;i=e[i].nxt)
#define en puts("")
#define LLM LONG_LONG_MAX
#define LLm LONG_LONG_MIN
#define pii pair<ll,ll>
typedef long long ll;
typedef double db;
using namespace std;
const ll INF=0x3f3f3f3f;
void read() {}
void OP() {}
void op() {}
template <typename T, typename... T2>
inline void read(T &_, T2 &... oth)
{
int __=0;
_=0;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
__=1;
ch=getchar();
}
while(isdigit(ch))
{
_=_*10+ch-48;
ch=getchar();
}
_=__?-_:_;
read(oth...);
}
template <typename T>
void Out(T _)
{
if(_<0)
{
putchar('-');
_=-_;
}
if(_>=10)
Out(_/10);
putchar(_%10+'0');
}
template <typename T, typename... T2>
inline void OP(T _, T2... oth)
{
Out(_);
putchar('\n');
OP(oth...);
}
template <typename T, typename... T2>
inline void op(T _, T2... oth)
{
Out(_);
putchar(' ');
op(oth...);
}
/*#################################*/
const ll N=2E5+10;
ll n,cnt,tot;
ll dp[N][2],w[N],dp_[N][2];
vector<ll> edge[N];
void add_edge(ll u,ll v,ll flag)
{
edge[u].emplace_back(v);
if(flag)
add_edge(v,u,0);
}
void dfs(ll u,ll fa)
{
dp[u][1]=1;
dp_[u][1]=edge[u].size();
dp_[u][0]=1;
for(auto v:edge[u])
{
if(v==fa)
continue;
dfs(v,u);
dp[u][0]+=max(dp[v][0],dp[v][1]);
dp[u][1]+=dp[v][0];
if(dp[v][0]>dp[v][1])
dp_[u][0]+=dp_[v][0];
else if(dp[v][0]<dp[v][1])
dp_[u][0]+=dp_[v][1];
else if(dp_[v][0]<dp_[v][1])
dp_[u][0]+=dp_[v][0];
else
dp_[u][0]+=dp_[v][1];
dp_[u][1]+=dp_[v][0];
}
}
void gg(ll u,ll fa,ll col)
{
if(col==1)
{
w[u]=edge[u].size();
++cnt;
}
else
w[u]=1;
tot+=w[u];
for(auto v:edge[u])
{
if(v==fa)
continue;
if(col==1)
gg(v,u,0);
else
{
if(dp[v][0]>dp[v][1])
gg(v,u,0);
else if(dp[v][0]<dp[v][1])
gg(v,u,1);
else if(dp_[v][0]<dp_[v][1])
gg(v,u,0);
else
gg(v,u,1);
}
}
}
int main()
{
read(n);
ll u,v;
rep(i,1,n-1)
{
read(u,v);
add_edge(u,v,1);
}
if(n==2)
{
op(2,2);
en;
op(1,1);
return 0;
}
ll p=1;
dfs(p,0);
if(dp[p][0]>dp[p][1])
gg(p,0,0);
else if(dp[p][0]<dp[p][1])
gg(p,0,1);
else if(dp_[p][0]<dp_[p][1])
gg(p,0,0);
else
gg(p,0,1);
op(cnt,tot);
en;
rep(i,1,n)
op(w[i]);
en;
}