Cuckoo Hashing

Description

One of the most fundamental data structure problems is the dictionary problem: given a set D of words you want to be able to quickly determine if any given query string q is present in the dictionary D or not. Hashing is a well-known solution for the problem. The idea is to create a function h : Σ* → [0..n-1] from all strings to the integer range 0, 1, .., n-1, i.e. you describe a fast deterministic program which takes a string as input and outputs an integer between 0 and n-1. Next you allocate an empty hash table T of size n and for each word w in D, you set T[h(w)] = w. Thus, given a query string q, you only need to calculate h(q) and see if T[h(q)] equals q, to determine if q is in the dictionary. Seems simple enough, but aren't we forgetting something? Of course, what if two words in D map to the same location in the table? This phenomenon, called collision, happens fairly often (remember the Birthday paradox: in a class of 24 pupils there is more than 50% chance that two of them share birthday). On average you will only be able to put roughly √n-sized dictionaries into the table without getting collisions, quite poor space usage!

A stronger variant is Cuckoo Hashing. The idea is to use two hash functions h1 and h2. Thus each string maps to two positions in the table. A query string q is now handled as follows: you compute both h1(q) and h2(q), and if T[h1(q)] = q, or T[h2(q)] = q, you conclude that q is in D. The name "Cuckoo Hashing" stems from the process of creating the table. Initially you have an empty table. You iterate over the words d in D, and insert them one by one. If T[h1(d)] is free, you set T[h1(d)] = d. Otherwise if T[h2(d)] is free, you set T[h2(d)] = d. If both are occupied however, just like the cuckoo with other birds' eggs, you evict the word r in T[h1(d)] and set T[h1(d)] = d. Next you put r back into the table in its alternative place (and if that entry was already occupied you evict that word and move it to its alternative place, and so on). Of course, we may end up in an infinite loop here, in which case we need to rebuild the table with other choices of hash functions. The good news is that this will not happen with great probability even if D contains up to n/2 words!

Input

On the first line of input is a single positive integer 1 ≤ t ≤ 50 specifying the number of test cases to follow. Each test case begins with two positive integers 1 ≤ m ≤ n ≤ 10000 on a line of itself, m telling the number of words in the dictionary and n the size of the hash table in the test case. Next follow m lines of which the ith describes the ith word di in the dictionary D by two non negative integers h1(di) and h2(di) less than n giving the two hash function values of the word di. The two values may be identical.

Output

For each test case there should be exactly one line of output either containing the string "successful hashing" if it is possible to insert all words in the given order into the table, or the string "rehash necessary" if it is impossible.

Sample Input

2
3 3
0 1
1 2
2 0
5 6
2 3
3 1
1 2
5 1
2 5

Sample Output

successful hashing
rehash necessary

裸2SAT

相同值的位置表示为 !A or !B 即可

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#define M 40005
using namespace std;
int all,be[],n,m,x,y;
int dfn[M],low[M],instack[M],belong[M],stack[M],stak,curr,num;
int e[M],ne[M],ee[M];
vector<int> vec[]; void add(int x,int y){
e[all]=y;
ee[all]=x;
ne[all]=be[x];
be[x]=all++;
}
void tarjan(int x){
instack[x]=;
stack[++stak]=x;
dfn[x]=low[x]=++curr;
for(int j=be[x];j!=-;j=ne[j])
if(!dfn[e[j]]){
tarjan(e[j]);
if(low[x]>low[e[j]]) low[x]=low[e[j]];
}else if(instack[e[j]]&&low[x]>low[e[j]])
low[x]=low[e[j]];
if(dfn[x]==low[x]){
int j;
++num;
do{
j=stack[stak--];
instack[j]=;
belong[j]=num;
}while(j!=x);
}
}
int solve(){
curr=stak=num=;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(instack,,sizeof(instack));
for(int i=;i<*n;i++)
if(!dfn[i]) tarjan(i);
bool flag=;
for(int i=;i<n;i++)
if(belong[*i]==belong[*i+]){
flag=;
break;
}
return flag;
}
int main()
{
int tt;
scanf("%d",&tt);
while(tt--)
{
for(int i=; i<=; i++)
vec[i].clear();
all=;
memset(be,-,sizeof(be));
scanf("%d%d",&n,&m);
for(int i=; i<n; i++)
{
scanf("%d%d",&x,&y);
for(vector<int>::iterator it=vec[x].begin(); it!=vec[x].end(); it++)
{
add(*it,*i+);
add(*i,(*it)^);
}
for(vector<int>::iterator it=vec[y].begin(); it!=vec[y].end(); it++)
{
add(*it,*i);
add(*i+,(*it)^);
}
vec[x].push_back(*i);
vec[y].push_back(*i+);
}
// for(int i=0; i<all; i++)
// printf("%d %d\n",ee[i],e[i]);
if(!solve()) printf("successful hashing\n");
else printf("rehash necessary\n");
}
return ;
}

看网上题解也可以用二分图匹配做,顺便写写练手

#include <cstdio>
#include <cstring>
#define M 80005
struct Edge{
int y,ne;
}e[M];
int be[M],pre[M],all,x,y,n,m;
bool vis[M];
void add(int x, int y)
{
e[all].y=y;
e[all].ne=be[x];
be[x]=all++;
}
void init()
{
all=;
memset(be,-,sizeof(be));
memset(pre,-,sizeof(pre));
}
bool dfs(int u)
{
for(int i=be[u]; i!=-; i=e[i].ne)
{
int v=e[i].y;
if(!vis[v])
{
vis[v]=;
if(pre[v]==- || dfs(pre[v]))
{
pre[v]=u;
return ;
}
}
}
return ;
}
int main()
{
int tt;
scanf("%d",&tt);
while(tt--)
{
init();
scanf("%d%d",&n,&m);
for(int i=; i<n; i++)
{
scanf("%d%d",&x,&y);
add(i,x+n);
add(i,y+n);
}
int ans=;
bool flag=;
for(int i=; i<n; i++)
{
memset(vis,,sizeof(vis));
if(!dfs(i))
{
flag=;
break;
}
}
if(flag) printf("successful hashing\n");
else printf("rehash necessary\n");
}
return ;
}

HDU 1672 Cuckoo Hashing的更多相关文章

  1. Cuckoo for Hashing(hash)hunnuoj

    Problem B:Cuckoo for HashingAn integer hash table is a data structure that supports insert, delete a ...

  2. Cuckoo for Hashing_双哈希表

    问题 B: Cuckoo for Hashing 时间限制: 1 Sec  内存限制: 64 MB提交: 24  解决: 12[提交][状态][讨论版] 题目描述 An integer hash ta ...

  3. Cuckoo hash算法分析——其根本思想和bloom filter一致 增加hash函数来解决碰撞 节省了空间但代价是查找次数增加

    基本思想: cuckoo hash是一种解决hash冲突的方法,其目的是使用简单的hash 函数来提高hash table的利用率,同时保证O(1)的查询时间 基本思想是使用2个hash函数来处理碰撞 ...

  4. Locality-sensitive hashing Pr[m(Si) = m(Sj )] = E[JSˆ (Si, Sj )] = JS(Si, Sj )

    A hash function that maps names to integers from 0 to 15. There is a collision between keys "Jo ...

  5. Java数据结构与算法解析(十二)——散列表

    散列表概述 散列表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值. 散列表的思路很简单,如果所有的键都是整数,那么就可以使用一个简单 ...

  6. 《大数据日知录》读书笔记-ch3大数据常用的算法与数据结构

    布隆过滤器(bloom filter,BF): 二进制向量数据结构,时空效率很好,尤其是空间效率极高.作用:检测某个元素在某个巨量集合中存在. 构造: 查询: 不会发生漏判(false negativ ...

  7. CMU Database Systems - Indexes

    这章主要描述索引,即通过什么样的数据结构可以更加快速的查询到数据 介绍Hash Tables,B+tree,SkipList 以及索引的并行访问 Hash Tables hash tables可以实现 ...

  8. 二. 大数据常用的算法和数据结构 <<大数据日知录>> 读书笔记

    基本上是hash实用的各种举例 布隆过滤器 Bloom Filter 常用来检测某个原色是否是巨量数据集合中的成员,优势是节省空间,不会有漏判(已经存在的数据肯定能够查找到),缺点是有误判(不存在的数 ...

  9. Go语言实现布谷鸟过滤器

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/453 介绍 在我们工作中,如果遇到如网页 URL 去重.垃圾邮件识别 ...

随机推荐

  1. select * from table where 1=1

    转自:http://www.dzwebs.net/2418.html 我们先来看看这个语句的结果:select * from table where 1=1,其中where 1=1,由于1=1永远是成 ...

  2. Careercup - Facebook面试题 - 4713484755402752

    2014-05-02 00:30 题目链接 原题: Given two arrays of sorted integers, merge them keeping in mind that there ...

  3. php发送get、post请求的几种方法

    方法1: 用file_get_contents 以get方式获取内容 <?php $url='http://www.domain.com/'; $html = file_get_contents ...

  4. 怎么让CentOS集群自动同步时间

    怎么让CentOS集群自动同步时间?首先机器要连外网,这样才能从互联网上同步时间,这是首先要了解的.好了,主要的方法如下: 在除了运行ntpd之外的机器上,执行: [html] # chkconfig ...

  5. 通过WebBrowser获取网页验证码

    /// <summary> /// 返回指定WebBrowser中图片<IMG></IMG>中的图内容 /// </summary> /// <p ...

  6. uva 11029

    看了别人的解法 发现了 modf 这个函数 取小数部分 /*********************************************************************** ...

  7. HTML中动态图片切换JQuery实现

    相信很多同学都注意到了,各大新闻或者娱乐网站都含有动态图片切换,那个漂亮的感觉让刚刚学习html的人,都非常好奇和心动.那下面就让我们看一下到底如何实现动态图片切换呢?看一下百度贴吧的效果图吧~ // ...

  8. PHP ServerPush

    原文:http://yorsal.com/archives/302 随着人们对Web即时应用需求的不断上升,Server Push(推送)技术在聊天.消息提醒尤其是社交网络等方面开始兴起,成为实时应用 ...

  9. Appboy 基于 MongoDB 的数据密集型实践

    摘要:Appboy 正在过手机等新兴渠道尝试一种新的方法,让机构可以与顾客建立更好的关系,可以说是市场自动化产业的一个前沿探索者.在移动端探索上,该公司已经取得了一定的成功,知名产品有 iHeartM ...

  10. gulp-css-spriter 雪碧图合成

    一.配置 gulp的雪碧图功能没有grunt那么强大,但是类似功能也支持,功能稍微弱一些,但是也很棒 npm地址:https://www.npmjs.com/package/gulp-css-spri ...