题解 CF1338B Edge Weight Assignment
小清新思维题。
先找一个不是叶子的节点,令它为根。
那么当且仅当,对于每一个非叶子节点,它包含的叶子节点到它的异或路径相等时,才满足题目要求。
考虑第一问,显然如果每个叶子的深度奇偶性相同,可以全填一样的数字,答案为 。反之为 (可以在一条链上试一试)。
对于第二问,定义 表示子树 最多能填多少种边权,转移方程如下。
简单理解就是,如果儿子中有叶子,那么每个叶子所连边的权值相等,其他的随便填。
复杂度 。
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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步