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 ...
随机推荐
- C++程序设计--实验二
第二次实验主要内容是函数重载,快速排序及其模板实现,简单的user类实现. 实验结论: 一.函数重载编程练习 /*编写重载函数add(),实现对int型,double型和Complex型数据的加法.在 ...
- PHP中时间戳和时区
时间戳 时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数. 时区 由于世界各国家与地区经度不同,地方时也有所不同,因此 ...
- 20155229 《信息安全系统设计基础》 Mypwd实现
Mypwd 内容 1 学习pwd命令 2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 3 实现mypwd 4 测试mypwd 学习pwd命令 通过man pwd查看 pwd命 ...
- 用 GSL 求解超定方程组及矩阵的奇异值分解(SVD) 2
接上一篇... 下面我们将 SVD 相关的功能封装成一个类,以方便我们提取 S 和 V 的值. 另外,当我们一个 A 有多组 x 需要求解时,也只需要计算一次 SVD 分解,用下面的类能减少很多计算量 ...
- JZOJ 10043 第k小数
Description 有两个非负整数数列,元素个数分别为N和M.从两个数列中分别任取一个数相乘,这样一共可以得到NM个数,询问这NM个数中第K小数是多少. 时间限制为20ms . Input 输入文 ...
- 经典简约风格教师求职简历免费word模板
20款经典简约风格教师求职简历免费word模板,也可用于其他专业和职业,个人免费简历模板,个人简历表免费,个人简历表格. 声明:该简历模板仅用于个人欣赏使用,请勿用于商业用途,谢谢. 下载地址:百度网 ...
- Analysis 图标分析 - loadrunner
analysis常见 /
- openstack horizon开发第一天
horizon插件构造 创建一个dashboardmkdir opesntack_dashboard/dashboards/mydashboardpython manage.py startdash ...
- 基于WebSocket协议的性能测试
互联网应用时代,用户获取信息的方式从传统媒体到新媒体,信息时效性对通信技术要求越来越高, HTTP协议已经不能适用.于是WebSocket出现了,它实现浏览器与服务器的全双工通信,服务端主动向客户端发 ...
- Codeblocks自动代码格式化快捷键(自带)
代码区域右击 点format use AStyle 估计也就是考试竞赛逼着用这个