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+ ...
- 跨域(Cross-Domain) AJAX for IE8 and IE9
1.有过这样一段代码,是ajax $.ajax({ url: "http://127.0.0.1:9001", type: "POST", data: JSON ...
- golang实现简单的栈
栈的ADT 数据 栈的数据对象集合为{a1,a2,a3...an},具有相同数据类型,有唯一前驱后续 操作 InitStack() *Stack //初始化操作,创建一个空栈 Clear() //清空 ...
- 在jupyter中安装R的kernal
网上有安装完anaconda后可以直接使用conda 命令安装R的kernal,本人电脑上已经安装了anaconda和R,因此使用手动安装的方式安装. 安装环境: windows 8.1 企业版 An ...
- c# multi-ply download ui
first neet add an user control "DownloadBar": /* Created by SharpDevelop. User: gwang Date ...
- P4211 [LNOI2014]LCA
P4211 [LNOI2014]LCA 链接 分析: 首先一种比较有趣的转化是,将所有点到1的路径上都+1,然后z到1的路径上的和,就是所有答案的deep的和. 对于多次询问,要么考虑有把询问离线,省 ...
- 腾讯云服务器linux Ubuntu操作系统搭建ftp服务器vsftpd
腾讯云服务器linux Ubuntu操作系统安装ftp服务器vsftpd 操作系统: Ubuntu Server 16.04.1 LTS 64位 下面我将系统重装, 一步一步从头开始,安装FTP服务器 ...
- cookie记住密码/base64加密(js控制)
cookie记住密码/base64加密(js控制) • 配置cookie //设置cookie function setCookie ( name, value, expdays ) { var ex ...
- SICP读书笔记 3.1
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
- ef5 数据库操作
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...