标签:cnt int Assignment indug ++ 异或 Edge maxn
大意:
给定一棵无根树,要求你任意设置n-1条边的边权.
使得任意叶子节点间边权的XOR值为0; |
\(\color{Red}{--------------------我是华丽的分割线(●ˇ∀ˇ●)-----------------------}\)
\(看上去很难吧??\)做起来也很难
\(\color{Red}{Ⅰ.考虑最小}\)
\(那请你先想个简单的问题,考虑两个叶子节点f最小值的情况。很容易想到我在路上全挂满1对吧?\)
\(但问题来了,如果两个叶子间的距离为奇数,就行不通了。这时候最小值怎么算呢?\)
\(全放1肯定不行,少放1个1也不行,这样要抵消成0的话还是要放1.\)
\(\color{Purple}{那就少放两个1,让这连个数异或后可以抵消掉1,这样并不难}\)
\(\color{Red}{Ⅱ.考虑最大}\)
\(这个似乎就很难了。但是一开始肯定希望把路上放满不同的数,这样肯定可以异或成0.\)
\(为什么?回想一下异或的性质,我是不是可以这样放权值\)
\(0000001,0000010,0000100,0001000......突然到最后,放一个11111111和前面全部抵消\)
\(完美!!这样我们的答案就是 n-1 !! 不过用脚想也知道没这么简单。什么时候不满足呢?\)
\(当叶子节点距离只有2的时候无法满足,2是XOR的特殊情况,想为0就必须放两个相同的。\)
#include <bits/stdc++.h>
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<n;i++)
{
int l,r;
cin>>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<<ans;
}
标签:cnt,int,Assignment,indug,++,异或,Edge,maxn 来源: https://www.cnblogs.com/iss-ue/p/12789533.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。