AcWing 880. 数字对生成树
原题链接
简单
作者:
王小强
,
2021-02-18 14:58:02
,
所有人可见
,
阅读 314
坑点太多了
// 除了根结点(root)外,每个结点 “有且只有” 一个父结点,root没有父结点。
// 可以用入度表,每个结点的入度的值是0或1,除此之外就是不合法的树。
// 本题的测试用例包含了多个根节点(多颗树)的情况。(那就是一个森林了forest!)要特判!
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <sstream>
#include <algorithm>
using namespace std;
int n, parent, child, seqId;
unordered_map<int, int> sequences;
unordered_map<int, int> indegrees;
unordered_map<int, vector<int>> graph; // adjacency list (directed graph)
string levelOrder(int root) {
queue<int> q{{root}};
ostringstream out;
while (not q.empty()) {
vector<int> tmp;
size_t sz = q.size();
while (sz--) {
const int cur = q.front(); q.pop();
tmp.emplace_back(cur);
for (const auto& child : graph[cur])
q.emplace(child);
}
sort(begin(tmp), end(tmp), [](const auto& a, const auto& b) {
return sequences[a] < sequences[b];
});
for (const auto& x : tmp) out << x << ',';
}
return out.str();
}
int main(void) {
scanf("%d", &n);
while (n--) {
scanf("%d,%d", &parent, &child);
auto children = graph[parent]; // deduplcation
if (find(begin(children), end(children), child) != end(children))
continue;
if (++indegrees[child] > 1)
return puts("Not a tree"), 0;
graph[parent].emplace_back(child);
if (!sequences.count(parent))
sequences[parent] = seqId++;
if (!sequences.count(child))
sequences[child] = seqId++;
}
int root = -1, root_count = 0; // root_count 为根节点的数量
for (const auto& p : sequences) {
root_count += !indegrees[p.first];
if (!indegrees[p.first]) root = p.first;
}
if (root_count != 1) return puts("Not a tree"), 0;
auto ans = levelOrder(root);
ans = ans.substr(0, ans.length() - 1);
printf("%s\n", ans.c_str());
}