Codeforces Round #683 (Div. 2, by Meet IT) E Xor Tree

题目传送门

题目大意

给n个点,每个点都有一个值 a i ,对于一个点,在n-1个点中找到与其异或值最小的点,并连一条双向边。求最少删除多少条边使其成为一个树。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int qs=2e5+7;
 4 int n,tree[qs<<5][2],tot=1,ans=qs,sum[qs<<5];
 5 void Insert(int x){ 
 6     int p=1;
 7     for(int i=30;i>=0;--i){
 8         int j=(x>>i)&1;
 9         if(!tree[p][j]){
10             tree[p][j]=++tot;
11         }
12         sum[p]++;
13         p=tree[p][j];
14     }
15 }
16 void dfs(int p,int deep,int cnt){
17     if(deep==30){
18         ans=min(ans,cnt);
19         return;
20     }
21     int pl=tree[p][0],pr=tree[p][1];
22     if(!pl && !pr) return;
23     else if(!pl){ //左子树空 进入右子树,不删边 
24         dfs(pr,deep+1,cnt);
25     }
26     else if(!pr){ //右子树空 
27         dfs(pl,deep+1,cnt);
28     }
29     else{
30         // 删除右子树  右子树节点保留一个 
31         dfs(pl,deep+1,cnt+sum[pr]-1);
32         // 删除左子树  左子树节点保留一个 
33         dfs(pr,deep+1,cnt+sum[pl]-1);
34     }
35 }
36 int main(){
37     std::ios::sync_with_stdio(false);
38     int  x;
39     cin>>n;
40     for(int i=1;i<=n;++i){
41         cin>>x;
42         Insert(x);
43     }
44     dfs(1,0,0);
45     cout<<ans<<"\n";
46     return 0;
47 }

借鉴博客

// 555大佬太强了

posted @ 2020-11-17 21:02  Suki_Sugar  阅读(119)  评论(0编辑  收藏  举报
Live2D