Description

Some major cities have subway systems in the form of a tree, i.e. between any pair of stations, there is one and only one way of going by subway. Moreover, most of these cities have a unique central station. Imagine you are a tourist in one of these cities
and you want to explore all of the subway system. You start at the central station and pick a subway line at random and jump aboard the subway car. Every time you arrive at a station, you pick one of the subway lines you have not yet travelled on. If there
is none left to explore at your current station, you take the subway line back on which you first came to the station, until you eventually have travelled along all of the lines twice,once for each direction. At that point you are back at the central station.
Afterwards, all you remember of the order of your exploration is whether you went further away from the central station or back towards it at any given time, i.e. you could encode your tour as a binary string, where 0 encodes taking a subway line getting you
one station further away from the central station, and 1 encodes getting you one station closer to the central station. 



Input

On the first line of input is a single positive integer n, telling the number of test scenarios to follow.Each test scenario consists of two lines, each containing a string of the characters '0' and '1' of length at most 3000, both describing a correct exploration
tour of a subway tree system.

Output

exploration tours of the same subway tree system, or the text "different" if the two strings cannot be exploration tours of the same subway tree system.

Sample Input

2
0010011101001011
0100011011001011
0100101100100111
0011000111010101

Sample Output

same
different

事实上题目意思就是求两个有根树是否同构,这个假设暴力法枚举的话。复杂度是O(N^2)。一中经典的做法是哈希。思想就是使得不同结构的树哈希值不同。而同构的树哈希值同样。

我这个也是參考别人写的。不同的是我先把01串转换为了树状结构表示。然后再递归求哈希值,这样好理解一点。

哈希的策略:先随机产生一系列随机数作为存到数组。接着从根节点出发。递归计算每一个子树的哈希值,将子树的哈希值相加然后和父节点自己相应的数组上的随机数相加得到父节点的哈希值。这个计算结果和子树的顺序是没有关系的,所以同构的树一哈希值一定是一样的。

对于异构的树,必定在某些节点计算的哈希值不同,因为都是随机产生的一些数字,所以他们相加值和另外一棵树哈希值同样的概率也会很低。(应该不能全然保证的,这里我们加了个取模m的操作。依据鸽巢原理,当树的数量超过m,必定有两个树的哈希值是会同样的,但这两个树却未必是同构的,不知道大家认为对不正确?)

import java.util.*;
public class SubwayTreeSstems1635 { static final int Hn=11000;
static int h[]=new int[Hn];
static Random rand=new Random(System.currentTimeMillis());
static int m=1000000007;
static int index=0;
/**
* @param args
*/
public static void main(String[] args) { run();
} private static void init() { for(int i=0;i<Hn;i++)
h[i]=(rand.nextInt()%m);
} public static void run()
{
Scanner in=new Scanner(System.in);
int T=in.nextInt();
init();
for(int t=0;t<T;t++)
{
String s1=in.next();
Node tree1=createTree(s1);
String s2=in.next();
Node tree2=createTree(s2);
/*System.out.println(tree1.children.size()+" "+tree2.children.size());
displayTree(tree1);
System.out.println();
displayTree(tree2);*/ int a=hash(tree1,1);
int b=hash(tree2,1);
//System.out.println(a+" "+b);
if(a==b)
{
System.out.println("same");
}
else
{
System.out.println("different");
}
}
} public static int hash(Node tree,int j)
{
int sum=h[j+5000];//j是树的高度
for(Node n:tree.children)
sum=(sum+h[j]*hash(n,j+1))%m;//把子树的哈希值加到父节点上去
return (sum*sum)%m; } private static Node createTree(String s) { char[] seq=s.toCharArray();
Node root=new Node(0);
Node p=root;
int index=1;
for(int i=0;i<seq.length;i++)
{
if(seq[i]=='0')
{
Node node =new Node(index++);
connect(p,node);
p=node;
}
else if(seq[i]=='1')
{
p=p.parent;
}
}
//if(p==root)
// System.out.println("create success!");
return root;
} private static void connect(Node p, Node node) { node.parent=p;
p.children.add(node);
} public static void displayTree(Node tree)
{
System.out.println(tree);
for(Node ch:tree.children)
displayTree(ch);
} } class Node
{
int id;
Node parent=null;
List<Node> children=new ArrayList<Node>();
public Node(int n)
{
id=n;
}
public String toString()
{
StringBuilder sb=new StringBuilder();
sb.append(id).append(": ");
for(Node n:children)
sb.append(n.id).append(" ");
return sb.toString();
}
}

poj-1635 Subway tree systems(推断两个有根树是否同构)-哈希法的更多相关文章

  1. poj 1635 Subway tree systems(树的最小表示)

    Subway tree systems POJ - 1635 题目大意:给出两串含有‘1’和‘0’的字符串,0表示向下搜索,1表示回溯,这样深搜一颗树,深搜完之后问这两棵树是不是同一棵树 /* 在po ...

  2. POJ 1635 Subway tree systems 有根树的同构

    POJ 1635 题目很简单 给个3000节点以内的根确定的树 判断是否同构.用Hash解决,类似图的同构,不过效率更高. #include<iostream> #include<c ...

  3. [POJ 1635] Subway tree systems (树哈希)

    题目链接:http://poj.org/problem?id=1635 题目大意:给你两棵树的dfs描述串,从根节点出发,0代表向深搜,1代表回溯. 我刚开始自己设计了哈希函数,不知道为什么有问题.. ...

  4. POJ 1635 Subway tree systems (树的最小表示法)

    题意:一串01序列,从一个点开始,0表示去下一个点,1表示回到上一个点,最后回到起点,遍历这棵树时每条边当且仅当走2次(来回) 给出两串序列,判断是否是同一棵树的不同遍历方式 题解:我们把每一个节点下 ...

  5. 【POJ】【1635】Subway Tree Systems

    树的最小表示法 给定两个有根树的dfs序,问这两棵树是否同构 题解:http://blog.sina.com.cn/s/blog_a4c6b95201017tlz.html 题目要求判断两棵树是否是同 ...

  6. HDU 1954 Subway tree systems (树的最小表示法)

    题意:用一个字符串表示树,0代表向下走,1代表往回走,求两棵树是否同构. 分析:同构的树经过最小表示会转化成两个相等的串. 方法:递归寻找每一棵子树,将根节点相同的子树的字符串按字典序排列,递归回去即 ...

  7. 【树哈希】poj1635 Subway tree systems

    题意:给你两颗有根树,判定是否同构. 用了<Hash在信息学竞赛中的一类应用>中的哈希函数. len就是某结点的子树大小,g是某结点的孩子数+1. 这个值也是可以动态转移的!具体见论文,所 ...

  8. POJ1635 Subway tree systems ——(判断树的同构,树的最小表示法)

    给两棵有根树,判断是否同构.因为同构的树的最小表示法唯一,那么用最小表示法表示这两棵树,即可判断同构.顺便如果是无根树的话可以通过选出重心以后套用之前的方法. AC代码如下: #include < ...

  9. POJ1635:Subway tree systems

    链接:http://poj.org/problem?id=1635 填坑树同构 题目给出的是除根外的括号序列表示. 其实只要跟你说hash大家都能写得出来…… hash函数取个效果别太差的就行了吧 # ...

随机推荐

  1. 解决TeamViewer的“现在无法捕捉画面。可能由于快速切换或者远程桌面断开或者最小化”问题

    公司项目接近尾声,因为测试的需要,就在客户局域网内部搭建了几台虚拟机做为服务器给客户测试用. 虚拟机环境:win2008R2 原先在客户那边用远程登录虚拟机操作,但考虑到回公司后无法远程登录,所以安装 ...

  2. vue2.0路由(跳转和传参)经典介绍

    声明式 <router-link :to="...">编程式router.push(...) router.push('home')                 / ...

  3. 通俗理解LDA主题模型(boss)

    0 前言 看完前面几篇简单的文章后,思路还是不清晰了,但是稍微理解了LDA,下面@Hcy开始详细进入boss篇.其中文章可以分为下述5个步骤: 一个函数:gamma函数 四个分布:二项分布.多项分布. ...

  4. 【DVWA】【SQL Injection(Blind)】SQL盲注 Low Medium High Impossible

    1.初级篇 Low.php 加单引号提交 http://localhost/DVWA-master/vulnerabilities/sqli_blind/?id=1'&Submit=Submi ...

  5. HDU_1242_Rescue

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1242 大意:迷宫搜索,'#'代表墙,'.'代表路,'x'代表守卫,每移动1格用1秒,杀死守卫用1秒,ang ...

  6. 洛谷——P1775 古代人的难题_NOI导刊2010提高(02)&& P1936 水晶灯火灵(斐波那契数列)

    P1775 古代人的难题_NOI导刊2010提高(02) P1936 水晶灯火灵 斐波那契数列 1.x,y∈[1…k],且x,y,k∈Z 2.(x^2-xy-y^2)^2=1 给你一个整数k,求一组满 ...

  7. 「 CODE[VS] P2853 」 方格游戏

    题目大意 给定一张 $n\times n$ 的网格.每个格子上都有一个系数 $a$,先下 $A$ 和 $B$ 两人选择两条 $(1,1)\rightarrow (n,n)$ 路径.要求着两条路径不能相 ...

  8. Git安装使用指南

    Git安装使用指南 Git原理示意图 1. 安装git Linux服务器版本为Redhat6.2-64,其他版本可能有些许不同 1.1 安装依赖包 在安装git前首先安装依赖包,包括的依赖包有: cv ...

  9. Python爬虫常用库安装

    建议更换pip源到国内镜像,下载会快很多:https://www.cnblogs.com/believepd/p/10499844.html requests pip3 install request ...

  10. python3.x Day1 用户登录程序练习

    训练1: 模拟登陆: 1. 用户输入帐号密码进行登陆 2. 用户信息保存在文件内 3. 用户密码输入错误三次后锁定用户 login2.py: #!/usr/bin/env python # -*- c ...