UVA 10729 - Treequivalence(暴力枚举)

Problem C: Treequivalence

The following grammar describes a textual notation for a tree with (not necessarily unique) vertex labels:
   tree ::= label
   tree ::= label ( subtrees )
   subtrees ::= tree
   subtrees ::= subtrees , tree
   label ::= A | B | C | ... | Z
That is, the representation of a tree consists of a label (which is an uppercase letter) or a label followed by a bracketed ordered list of trees separated by commas.

In order to draw such a tree on paper, we must write each label on the page, such that the labels for the subtrees of a vertex are positioned counter-clockwise about the vertex. The labels must be positioned such that non-intersecting line segments connect each vertex to each of its subtrees. That is to say, we draw the normal planar representation of the tree, preserving the order of subtrees. Beyond these constraints, the position, shape, and size of the representation is arbitrary.

For example, a possible graphical representation for A(B(C,D),E) is  .

Given the textual representation for two trees, you are to determine whether or not they are equivalent. That is, do they share a common paper representation?

The first line of input contains t, the number of test cases. Each test case consists of two lines, each specifying a tree in the notation described above. Each line will contain at most 200 characters, and no white space. For each test case, output a line containing "same" or "different" as appropriate.

Sample Input

2
A(B(C,D),E)
E(A,B(C,D))
A(B(C,D),E)
E(A(B(C,D)))

Output for Sample Input

different
same

题意:给两棵树,判断是否相同,注意结点可能字母是相同的。

思路:由于有结点可能字母相同,就变得麻烦了,以第2颗树的每个结点作为根去建树,在比较两棵树是否相同,对于每个结点的情况,利用map进行映射,可以简单比较,总之是很恶心的一题,代码是参考网上的题解写的。

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
const int N = 128;

int T;
struct Tree {
	int cnt;
	char node[N];
	vector<int> g[N];
	void clear() {
		cnt = 0;
		memset(node, 0, sizeof(node));
		memset(g, 0, sizeof(g));
	}
}T1, T2;
map<vector<int>, int> vis;

int read(Tree &T, int fa) {
	int x = T.cnt++;
	if (fa >= 0) T.g[x].push_back(fa);
	char c;
	scanf(" %c %c", &T.node[x], &c);
	if (c != '(') {
		ungetc(c, stdin);
		return x;
	}
	while (1) {
		T.g[x].push_back(read(T, x));
		if (scanf("%c", &c) != 1 || c != ',') break;
	}
	return x;
}

int solve(Tree T, int u, int fa) {
	vector<int> vi;
	if (fa < 0) {
		for (int i = 0; i < T.g[u].size();i ++) {
			int v = T.g[u][i];
			if (v == fa) continue;
			vi.push_back(solve(T, v, u));
		}
		int best = 0;
		int m = vi.size();
		for (int s = 1; s < m; s++) {
			for (int i = best, j = s, k = 0; k < m; k++) {
				if (vi[i] != vi[j]) {
					if (vi[j] < vi[i]) best = s;
					break;
				}
				if (++i >= m) i = 0;
				if (++j >= m) j = 0;
			}
		}
		rotate(vi.begin(), vi.begin() + best, vi.end());
	}
	else {
		int i;
		for (i = 0; T.g[u][i] != fa; i++);
		while (1) {
			if (++i >= T.g[u].size()) i = 0;
			int v = T.g[u][i];
			if (v == fa) break;
			vi.push_back(solve(T, v, u));
		}
	}
	vi.push_back(T.node[u]);
	int k;
	if (vis.count(vi))
		k = vis[vi];
	else {
		k = vis.size();
		vis[vi] = k;
	}
	return k;
}

bool judge() {
	if (T1.cnt != T2.cnt) return false;
	vis.clear();
	for (int i = 0; i < T1.cnt; i++)
		if (solve(T1, i, -1) == solve(T2, 0, -1)) return true;
		return false;
}

int main() {
	scanf("%d", &T);
	while (T--) {
		T1.clear(); T2.clear();
		read(T1, -1); read(T2, -1);
		printf("%s\n", judge()?"same":"different");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值