您的位置:首页 > 其它

zoj 3602 Count the Trees (dfs+哈希)

2017-05-05 15:05 295 查看
题意:

给出两棵树,问这两棵树有多少对子树,分别来自两棵树且结构相同。

思路:

一开始想着去给没课字符编号,然后map统计,但是没想出编号的办法。

编号的话我们可以根据二叉树每个节点的两个儿子来编号,pair<int,int>pair中两个值分别表示出了两个左右子树的结构,这棵树的结构也就表示出来了,这种做法倒是加深了对树的理解,已经如何构造编号也是深受启发。

然后对两颗树分别dfs就可以了。

但是我在dfs函数里,每次用到pair都重新make_pair结果导致在递归的时候爆栈了,一直segmentation fault,用一个变量记录pair,每次 调用就过了。

不过可气的是一开始用的是C++0x (g++ 4.7.2)交的,原来爆栈的代码往C++
(g++ 4.7.2)一交就过了,编译器的不同造成的结果差异真的很大。。

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <map>
#include <iostream>
#include <vector>

#define ps push_back
#define LL long long
#define fir first
#define sec second
#define mk make_pair
using namespace std;
const int maxn=1e6+5;
int cnt, n, m;
struct node
{
int l,r;
}tree[maxn];
long long ans;
map<pair<int, int>, int>mp[3];
long long book[maxn];

int  dfs(int x, int y)
{
pair<int, int >e;
int a, b, i;
a=b=-1;
if(tree[x].l!=-1)a=dfs(tree[x].l, y);
if(tree[x].r!=-1)b=dfs(tree[x].r, y);
e.fir=a,e.sec=b;
if(mp[y].find(e)!=mp[y].end())
{
i=mp[y][e];
book[i]++;
return i;
}
else
{
mp[y][e]=cnt++;
book[cnt-1]++;
return cnt-1;
}
}

int  dfs2(int x)
{
pair<int, int>e;
int a, b, i;
a=b=-1;
if(tree[x].l!=-1)a=dfs2(tree[x].l);
if(tree[x].r!=-1)b=dfs2(tree[x].r);
e.fir=a,e.sec=b;
if(a==-2 || b==-2)return -2;
if(mp[0].find(e)!=mp[0].end())
{
i=mp[0][e];
ans+=book[i];
return i;
}
else return -2;
}
int main()
{
int t, i, j, x, y;
cin>>t;
while(t--)
{
memset(book, 0, sizeof book);
cnt=0;
ans=0;
scanf("%d%d", &n, &m);
for(i=1; i<=n; i++)
{
scanf("%d%d", &tree[i].l, &tree[i].r);
}
dfs(1, 0);
for(i=1; i<=m; i++)
{
scanf("%d%d", &tree[i].l, &tree[i].r);
}
dfs2(1);
printf("%lld\n", ans);
mp[0].clear();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: