P10477 Subway tree systems 题解,c++ 树相关题目

题目

poj 链接
洛谷链接

n n n 组数据,每组数据给定两个 01 01 01 串(长度不超过 3000 3000 3000),意思如下:

  • 对于每一个 0 0 0,代表该节点有一个子节点,并前往该子节点。
  • 对于每一个 1 1 1,代表返回该节点的父亲节点。

求两个字符串说表示的树是否同构。
在这里插入图片描述

思路

考虑对于每一个节点进行递归处理(因为可以知道一个大问题可以拆成多个小问题进行计算)。为方便后续操作,可虚构一个根节点的父亲节点(即在字符串开头加上 0 0 0,结尾加上 1 1 1)。

对于每一个节点,我们可以获得一个字符串代表该节点的子树,首先去掉头尾的字符(即去掉通往父亲节点的边),记 S S S 为字符串, c n t cnt cnt 表示 S S S 0 0 0 i i i 0 0 0 的数量与 1 1 1 的数量的差, j j j 表示儿子的数量。容易得到以下结论:

  • 对于 S i = 0 S_i = 0 Si=0,则 c n t ← c n t + 1 cnt \gets cnt + 1 cntcnt+1
  • 对于 S i = 0 S_i = 0 Si=0,则 c n t ← c n t − 1 cnt \gets cnt - 1 cntcnt1
  • 对于 c n t = 0 cnt = 0 cnt=0,即一个儿子已经遍历结束,则 j ← j + 1 j \gets j + 1 jj+1,并统计前一个儿子所代表的子串进行递归。

如果全部儿子所代表的子串递归完毕,可按照字符串排序的方式排列儿子所代表的字符串,并在头尾添上 01 01 01。可以发现,对于两个同构的树,以上操作后获得的字符串相等。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int T;
string a,b;
string paixu(string x) {
	//cout<<x<<endl;
	// 分离操作
	string y = x;
	int num = x.size(),cnt = 0;
	x = "";
	if(num <= 2) return y;
	for(int i = 1;i < num - 1;i++) x += y[i];
	num -= 2;
	string new_string[1505];
	int j = 1;
	for(int i = 0;i < num;i++) {
		if(x[i] == '0') cnt++,new_string[j] += '0';
		else cnt--,new_string[j] += '1';
		if(cnt == 0) {
			j++;
		}
	}
	j--;
	//递归
	for(int i = 1;i <= j;i++) new_string[i] = paixu(new_string[i]);
	//排序
	for(int i = j;i >= 1;i--) {
		for(int k = 1;k < i;k++) {
			if(new_string[k] > new_string[k + 1]) swap(new_string[k],new_string[k + 1]);
		}
	}
	for(int i = 2;i <= j;i++) new_string[1] += new_string[i];
	//cout<<("0" + new_string[1] + "1")<<endl;
	return ("0" + new_string[1] + "1");
}
signed main() {
	scanf("%lld",&T);
	while(T--) {
		cin >> a >> b;
		a = "0" + a + "1";
		b = "0" + b + "1";
		if(paixu(a) == paixu(b)) printf("same\n");
		else printf("different\n");
	}
    return 0;
}


  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值