Edge Weight Assignment(树-异或-贪心)
发布日期:2021-06-30 10:13:26 浏览次数:3 分类:技术文章

本文共 2554 字,大约阅读时间需要 8 分钟。

大意: 给定一棵无根树,要求你任意设置n-1条边的边权. 使得任意叶子节点间边权的XOR值为0; 此时,令f为所有边权数值不同的个数,求最小的f和最大的f.

− − − − − − − − − − − − − − − − − − − − 我 是 华 丽 的 分 割 线 ( ● ˇ ∀ ˇ ● ) − − − − − − − − − − − − − − − − − − − − − − − \color{Red}{--------------------我是华丽的分割线(●ˇ∀ˇ●)-----------------------} 线(ˇˇ)

看 上 去 很 难 吧 ? ? 看上去很难吧?? ??做起来也很难

Ⅰ . 考 虑 最 小 \color{Red}{Ⅰ.考虑最小} .

那 请 你 先 想 个 简 单 的 问 题 , 考 虑 两 个 叶 子 节 点 f 最 小 值 的 情 况 。 很 容 易 想 到 我 在 路 上 全 挂 满 1 对 吧 ? 那请你先想个简单的问题,考虑两个叶子节点f最小值的情况。很容易想到我在路上全挂满1对吧? f1?

但 问 题 来 了 , 如 果 两 个 叶 子 间 的 距 离 为 奇 数 , 就 行 不 通 了 。 这 时 候 最 小 值 怎 么 算 呢 ? 但问题来了,如果两个叶子间的距离为奇数,就行不通了。这时候最小值怎么算呢? ?

全 放 1 肯 定 不 行 , 少 放 1 个 1 也 不 行 , 这 样 要 抵 消 成 0 的 话 还 是 要 放 1. 全放1肯定不行,少放1个1也不行,这样要抵消成0的话还是要放1. 11101.

那 就 少 放 两 个 1 , 让 这 连 个 数 异 或 后 可 以 抵 消 掉 1 , 这 样 并 不 难 \color{Purple}{那就少放两个1,让这连个数异或后可以抵消掉1,这样并不难} 1,1

Ⅱ . 考 虑 最 大 \color{Red}{Ⅱ.考虑最大} .

这 个 似 乎 就 很 难 了 。 但 是 一 开 始 肯 定 希 望 把 路 上 放 满 不 同 的 数 , 这 样 肯 定 可 以 异 或 成 0. 这个似乎就很难了。但是一开始肯定希望把路上放满不同的数,这样肯定可以异或成0. 0.

为 什 么 ? 回 想 一 下 异 或 的 性 质 , 我 是 不 是 可 以 这 样 放 权 值 为什么?回想一下异或的性质,我是不是可以这样放权值 ?

0000001 , 0000010 , 0000100 , 0001000...... 突 然 到 最 后 , 放 一 个 11111111 和 前 面 全 部 抵 消 0000001,0000010,0000100,0001000......突然到最后,放一个11111111和前面全部抵消 0000001,0000010,0000100,0001000......11111111

完 美 ! ! 这 样 我 们 的 答 案 就 是 n − 1 ! ! 不 过 用 脚 想 也 知 道 没 这 么 简 单 。 什 么 时 候 不 满 足 呢 ? 完美!!这样我们的答案就是 n-1 !! 不过用脚想也知道没这么简单。什么时候不满足呢? !!n1!!?

当 叶 子 节 点 距 离 只 有 2 的 时 候 无 法 满 足 , 2 是 X O R 的 特 殊 情 况 , 想 为 0 就 必 须 放 两 个 相 同 的 。 当叶子节点距离只有2的时候无法满足,2是XOR的特殊情况,想为0就必须放两个相同的。 22XOR0

#include 
using namespace std;const int maxn=2e5+5;struct p{ int to,nxt;}d[maxn];int n,head[maxn],cnt=1;void add(int u,int v){ d[cnt].nxt=head[u],d[cnt].to=v,head[u]=cnt++;}int indug[maxn],deep[maxn],ji,ou,father[maxn];void dfs(int u,int fa){ deep[u]=deep[fa]+1; if(indug[u]==1) { if(deep[u]%2) ji=1; else ou=1; father[fa]++; return; } for(int i=head[u];i;i=d[i].nxt) if(d[i].to!=fa) dfs(d[i].to,u);}int main(){ cin>>n; for(int i=1;i
>l>>r; add(l,r);add(r,l); indug[l]++,indug[r]++; } int root; for(int i=1;i<=n;i++) if(indug[i]!=1) root=i;//随便找一个不是叶子的节点为根 dfs(root,root); if(ji&&ou) cout<<3<<" "; else cout<<1<<" "; int ans=n-1; for(int i=1;i<=n;i++) if(father[i]) ans=ans-father[i]+1; cout<

转载地址:https://issue-is-vegetable.blog.csdn.net/article/details/105809348 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Constant Palindrome Sum(贪心-RMQ)
下一篇:字典树板子

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2024年04月16日 07时06分36秒