zoj 1674 Family Tree

博客详细介绍了ZOJ 1674题目的解题思路,重点讨论了利用nds数组在建立家族树过程中的关键应用。
摘要由CSDN通过智能技术生成

这道题目建树精髓点在于nds数组的使用

#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<map>
using namespace std;

struct node {
	node() {};
	node(string _name, int _k): name(_name), k(_k) {};
	string name;
	int k;
	node *par;
	node *sub[1001];
} *nds[1001];
node *root;
map<string, node*> getpar;

bool isans(node *nd, string name) {
	while (1) {
		if (nd->name == name)return true;
		if (nd == root)break;
		nd = nd->par;
	}
	return false;
}

int main() {
	int n, m, i, j, t, len, k, res;
	string str, newstr, name1, s1, s2, rel, s3, name2;
	char ch[256];
	map<string, node*>::iterator it, it1;
	while (scanf("%d%d", &n, &m) && n) {
		getpar.clear();
		cin >> str;
		root = new node(str, 0);
		nds[0] = root;
		cin.ignore();
		for (i = 1; i < n; i++) {//建树
			cin.getline(ch, 256);
			str = string(ch);
			len = str.size();
			for (j = 0, t = 0; j < len; j++, t++) {
				if (str[j] != ' ')break;
			}
			k = nds[t - 1]->k;
			newstr = str.substr(j, len - j);
			nds[t - 1]->sub[k] = new node(newstr, 0);
			nds[t] = nds[t - 1]->sub[k];
			nds[t]->par = nds[t - 1];
			nds[t - 1]->k = k + 1;
			getpar[newstr] = nds[t - 1];
		}

		for (i = 0; i < m; i++) {
			cin >> name1 >> s1 >> s2 >> rel >> s3 >> name2;
			name2 = name2.substr(0, name2.size() - 1);
			res = 0;
			if (rel[0] == 'c') {
				it = getpar.find(name1);
				if (it != getpar.end() && it->second->name == name2) res = 1;
			} else if (rel[0] == 'a') {
				it = getpar.find(name2);
				if (it != getpar.end() && isans(it->second, name1)) res = 1;
			} else if (rel[0] == 's') {
				it = getpar.find(name1);
				it1 = getpar.find(name2);
				if (it != getpar.end() && it1 != getpar.end() && it->second == it1->second)res = 1;
			} else if (rel[0] == 'p') {
				it = getpar.find(name2);
				if (it != getpar.end() && it->second->name == name1) res = 1;
			} else if (rel[0] == 'd') {
				it = getpar.find(name1);
				if (it != getpar.end() && isans(it->second, name2)) res = 1;
			}

			if (res) {
				printf("True\n");
			} else {
				printf("False\n");
			}
		}
		printf("\n");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值