题解 CF1338B Edge Weight Assignment

小清新思维题。

先找一个不是叶子的节点,令它为根。

那么当且仅当,对于每一个非叶子节点,它包含的叶子节点到它的异或路径相等时,才满足题目要求。

考虑第一问,显然如果每个叶子的深度奇偶性相同,可以全填一样的数字,答案为 1。反之为 3(可以在一条链上试一试)。

对于第二问,定义 fi 表示子树 i 最多能填多少种边权,转移方程如下。

fi=(json(i)jleavesfj+1)+[json(i),jleaves]

简单理解就是,如果儿子中有叶子,那么每个叶子所连边的权值相等,其他的随便填。

复杂度 O(n)

code:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,dep[N],f[N],lv[N];
vector<int>adj[N];
void dfs(int u,int lst){
  dep[u]=dep[lst]+1;
  if(lv[u])return;
  bool fg=0;
  for(int i=0;i<adj[u].size();++i){
    int v=adj[u][i];if(v==lst)continue;
    dfs(v,u);
    if(lv[v])fg=1;
    else f[u]+=f[v]+1;
  }
  f[u]+=fg;
}
int main(){
  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  cin>>n;
  for(int i=1;i<n;++i){
    int u,v;cin>>u>>v;
    adj[u].push_back(v);adj[v].push_back(u);
  }
  int rt;
  for(int i=1;i<=n;++i){
    if(adj[i].size()==1)lv[i]=1;
    else rt=i;
  }
  dep[0]=-1;
  dfs(rt,0);
  int cnt=0,cnt2=0;
  for(int i=1;i<=n;++i){
    if(adj[i].size()>1)continue;
    if(dep[i]&1)++cnt;
    else ++cnt2;
  }
  if(cnt&&cnt2)cout<<3<<" ";
  else cout<<1<<" ";
  cout<<f[rt]<<endl;
  return 0;
}

本文作者:HQJ2007

本文链接:https://www.cnblogs.com/HQJ2007/p/17561334.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   HQJ2007  阅读(12)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起