[jobdu]树的子结构
判断一棵树B是否是A的子树,对A做DFS,然后不断判断是否和B相同。
其实也可以不对A做DFS,直接遍历A中的每个节点和B做树的比较就行了。
#include <iostream> #include <vector> using namespace std; bool sameTree(int a, int b, vector<vector<int> > &treeA, vector<vector<int> > &treeB, vector<int> &valA, vector<int> &valB) { if (valA[a] != valB[b]) return false; if (treeB[b].size() == 0) return true; if (treeA[a].size() != treeB[b].size()) return false; for (int i = 0; i < treeA[a].size(); i++) { if (!sameTree(treeA[a][i], treeB[b][i], treeA, treeB, valA, valB)) return false; } return true; } bool subTree(vector<vector<int> > &treeA, vector<vector<int> > &treeB, vector<int> &valA, vector<int> &valB, int root) { if (sameTree(root, 1, treeA, treeB, valA, valB)) { return true; } for (int i = 0; i < treeA[root].size(); i++) { if (subTree(treeA, treeB, valA, valB, treeA[root][i])) { return true; } } return false; } int main() { int n, m; while (cin >> n >> m) { vector<vector<int> > treeA(n+1); vector<vector<int> > treeB(m+1); vector<int> valA(n+1); vector<int> valB(m+1); for (int i = 1; i <= n; i++) { int tmp; cin >> tmp; valA[i] = tmp; } for (int i = 1; i <= n; i++) { int cnt; cin >> cnt; while (cnt--) { int x; cin >> x; treeA[i].push_back(x); } } for (int i = 1; i <= m; i++) { int tmp; cin >> tmp; valB[i] = tmp; } for (int i = 1; i <= m; i++) { int cnt; cin >> cnt; while (cnt--) { int x; cin >> x; treeB[i].push_back(x); } } if (m == 0 || n == 0) { cout << "NO" << endl; continue; } if (subTree(treeA, treeB, valA, valB, 1)) { cout << "YES" << endl; } else { cout << "NO" << endl; } } }