poj 1635 Subway tree systems(树的同构,经典)

题意:
一个有根树。给一种用01序列来表示该树的方式,0表示前进(沿没有访问过的边),1表示沿树边回退。
一个树当然会有多种表示, 问题是给出两个序列,问是否表示同一颗树。
思路:
感觉判断树的同构是个很广的问题。
不过就此题而言,可以对一颗树的所有表示序列,都可以用递归的方式把它们变成一个。(先划分子树,按字典序重排)
也有用dp做的,还有哈希的。。是很值得研究的一题
这道题引起我对两个问题的思考,对于一颗有根树,它的最小表示是什么?无根树呢?
无根树可能需要考虑具有某个度的节点有多少个,以及其相邻关系。。

// 代码考虑了非法输入,有些凌乱 = =!
string go (const string & s) {
    string ret;
    vector<string> subs;

    int i = 0, j = 0, cnt = 0, len = s.length();
    for (j=0;j<len;++j) {
        if (s[j] == '0')
            cnt += 1;
        else if (s[j] == '1')
            cnt -= 1;

        if (!cnt) {
            if (s[i] != '0' || s[j] != '1') return "";
            if (j-i+1 == 2)
                subs.push_back(s.substr(i, 2));
            else {
                string tmp = go (s.substr(i+1, j-i));
                if (tmp == "") return "";
                subs.push_back('0' + tmp + '1');
            }
            i = j+1;
        }
    }
    sort(subs.begin(), subs.end());
    for (int i=0;i<subs.size();++i) ret += subs[i];
    return ret;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.in", "r", stdin);
#endif
    string sa, sb;
    int n;
    cin >> n;
    while (n--) {
        cin >> sa >> sb;
        string x = go (sa), y = go (sb);
        if (x == y) cout << "same\n";
        else cout << "different\n";
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值