BNUOJ 52318 Be Friends prim+Trie
题目链接:
https://acm.bnu.edu.cn/v3/problem_show.php?pid=52318
B. Be Friends
Case Time Limit: 2500msMemory Limit: 524288KB
题意
给你n个点,每个点有一个权值a[i],对于两个点u,v,他们之间的边的权值为a[u]^a[v],现在让你求一颗最小生成树。
题解
Trie可以求离点u最近的点v(既u^v最小),利用这一点,我们用prim来求最小生成树, 可以用优先队列维护一下离我们已经扩展的集合的最近的点,最近的点是可以用Trie处理出来的。
代码
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxnode=2e6+10;
const int maxn=1e5+10;
struct Node {
int u,v;
bool operator < (const Node& tmp) const {
return (u^v)>(tmp.u^tmp.v);
}
Node(int u,int v):u(u),v(v) {}
};
///ch[0]为超级节点,不止是代表第一个点,很多点会连到上面,所以它的cntv必须为0,代表着终结。
struct Trie {
int ch[maxnode][2];
//cntv统计子树下的单词节点个数,val记录单词节点
int cntv[maxnode],val[maxnode];
int sz,cnt;
Trie() {
sz=1;
clr(ch[0],0);
cnt=0;
}
void insert(int x) {
cnt++;
int arr[44]= {0},tot=0,tmp=x;
while(tmp) {
arr[++tot]=tmp&1;
tmp>>=1;
}
int u=0;
for(int i=33; i>=1; i--) {
int c=arr[i];
if(!ch[u][c]) {
clr(ch[sz],0);
cntv[sz]=0;
val[sz]=-10086;
ch[u][c]=sz++;
}
u=ch[u][c];
cntv[u]++;
}
val[u]=x;
}
int query(int x) {
if(cnt==0) return -1;
int arr[44]= {0},tot=0,tmp=x;
while(tmp) {
arr[++tot]=tmp&1;
tmp>>=1;
}
int u=0;
for(int i=33; i>=1; i--) {
int c=arr[i];
if(cntv[ch[u][c]]) {
u=ch[u][c];
} else {
u=ch[u][c^1];
}
}
return val[u];
}
void del(int x) {
cnt--;
int arr[44]= {0},tot=0,tmp=x;
while(tmp) {
arr[++tot]=tmp&1;
tmp>>=1;
}
int u=0;
for(int i=33; i>=1; i--) {
int c=arr[i];
cntv[ch[u][c]]--;
u=ch[u][c];
}
}
} trie;
int arr[maxn],n;
map<int,bool> mp;
int main() {
scf("%d",&n);
for(int i=1; i<=n; i++) scf("%d",&arr[i]);
sort(arr+1,arr+n+1);
n=unique(arr+1,arr+n+1)-arr-1;
for(int i=2; i<=n; i++) {
trie.insert(arr[i]);
}
priority_queue<Node> pq;
if(n==1) {
prf("0\n");
return 0;
}
///prim求最小生成树
int tmp=trie.query(arr[1]);
pq.push(Node(arr[1],tmp));
mp[arr[1]]=true;
LL ans=0;
for(int i=2; i<=n; i++) {
while(mp[pq.top().v]){
int u=pq.top().u;
pq.pop();
int v=trie.query(u);
if(v>=0){
// prf("f(%d,%d)\n",u,v);
pq.push(Node(u,v));
}
}
int u=pq.top().u,v=pq.top().v;
pq.pop();
trie.del(v);
mp[v]=true;
ans+=u^v;
int u2=trie.query(u);
if(u2>=0){
pq.push(Node(u,u2));
}
int v2=trie.query(v);
if(v2>=0){
pq.push(Node(v,v2));
}
}
prf("%lld\n",ans);
return 0;
}
BNUOJ 52318 Be Friends prim+Trie的更多相关文章
- bnuoj 25662 A Famous Grid (构图+BFS)
http://www.bnuoj.com/bnuoj/problem_show.php?pid=25662 #include <iostream> #include <stdio.h ...
- 【CF888G】Xor-MST(最小生成树,Trie树)
[CF888G]Xor-MST(最小生成树,Trie树) 题面 CF 洛谷 题解 利用\(Kruskal\)或者\(Prim\)算法都很不好计算. 然而我们还有一个叫啥来着?\(B\)啥啥的算法,就叫 ...
- BNUOJ 12756 Social Holidaying(二分匹配)
题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=12756 Social Holidaying Time Limit: 3000ms Memo ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- 基于trie树做一个ac自动机
基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...
- 基于trie树的具有联想功能的文本编辑器
之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...
- [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)
Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...
- hihocoder-1014 Trie树
hihocoder 1014 : Trie树 link: https://hihocoder.com/problemset/problem/1014 题意: 实现Trie树,实现对单词的快速统计. # ...
- 【BZOJ-2938】病毒 Trie图 + 拓扑排序
2938: [Poi2000]病毒 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 609 Solved: 318[Submit][Status][Di ...
随机推荐
- Gym100920J
求Ax+By<=C,非负整数对(x,y)的个数 首先令y=0;则x<=(C/A);ans=(C/A)+1; 将Ax+By=C反转之后利用类欧几里得算法:f(a,b,c,n)=∑((a*i+ ...
- SM30 客户端 有“不可修改”的状态
SM30维护自定义数据表时,遇到提示信息,有“不可修改”的状态,无法修改数据. 查询详细信息,有一条:客户端特定对象不能在此客户端中进行更改. 检查了一下自定表设置,发现自定义表之前创建时,Deliv ...
- redis 数据库随笔 (一)
redis数据库的基本类型分析: 1.string 最基本的数据类型.只存贮一个值,key-value,最大值存储512M. 创建命令:hmset 读取命令:hget 2.hash 集合,存储为一个 ...
- 用uliweb 创建项目
创建项目 ***@Android:~# uliweb makeproject ablog ***@Android:~# cd ablog/ ***@Android:~/ablog# ls apps f ...
- [CF1027F]Session in BSU[最小基环树森林]
题意 有 \(n\) 门课程,每门课程可以选择在 \(a_i\) 或者 \(b_i\) 天参加考试,每天最多考一门,问最早什么时候考完所有课程. \(n\leq 10^6\). 分析 类似 [BZOJ ...
- Textarea的readonly问题
textarea的readonly属性,不能用setAttribute方法设置,只能类似textarea.readOnly = true|false的写法. 原因: setAttribute只能设置一 ...
- 亿级PV请求的三种负载均衡技术
在互联网+不断渗透到生活中的今天,各种各样的网络服务存在在我们身边,他们的访问流量也是大得惊人.一个大型网站(百万PV以上)想要正常访问,单单靠一台服务器是不可能提供稳定服务的.这时候就需要用负载均衡 ...
- Python调用matplotlib实现交互式数据可视化图表案例
交互式的数据可视化图表是 New IT 新技术的一个应用方向,在过去,用户要在网页上查看数据,基本的实现方式就是在页面上显示一个表格出来,的而且确,用表格的方式来展示数据,显示的数据量会比较大,但是, ...
- JavaScript中的null和undefined
null :表示无值;undefined : 表示一个未声明的变量, 或已声明但没有赋值的变量, 或一个并不存在的对象属性. ==运算符将两 ...
- 关于big-endian和little-endian
详解大端模式和小端模式 一.大端模式和小端模式的起源 关于大端小端名词的由来,有一个有趣的故事,来自于Jonathan Swift的<格利佛游记>:Lilliput和Blefuscu这两个 ...