-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathP615.cpp
90 lines (89 loc) · 2.27 KB
/
P615.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
int main() {
int x, y;
for(int cas = 1; true; ++cas) {
// Read edges:
set<int> nodes;
vector<PI> edges;
vector<PI> redges;
bool tree = true;
while(true) {
cin >> x >> y;
if(x < 0 && y < 0)
return 0;
if(x == 0 && y == 0)
break;
edges.push_back(PI(x,y));
redges.push_back(PI(y,x));
if(nodes.find(x) == nodes.end())
nodes.insert(x);
if(nodes.find(y) == nodes.end())
nodes.insert(y);
if(x == y) {
tree = false;
//cerr << "Node pointing to itself: " << x << "->" << y << endl;
}
}
if(edges.empty()) {
cout << "Case " << cas << " is a tree." << endl;
continue;
}
sort(edges.begin(), edges.end());
sort(redges.begin(), redges.end());
map<int,int> edgeStarts, redgeStarts;
int prev = -1;
FORUI(edges.size()) {
if(edges[i].first != prev) {
edgeStarts[edges[i].first] = (int)i;
prev = edges[i].first;
}
}
int rprev = -1;
FORUI(redges.size()) {
if(redges[i].first != rprev) {
redgeStarts[redges[i].first] = (int)i;
rprev = redges[i].first;
}
}
// Find root:
int root = *nodes.begin();
set<int> marked;
marked.insert(root);
while(tree && redgeStarts.find(root) != redgeStarts.end()) {
root = redges[redgeStarts[root]].second;
if(marked.find(root) != marked.end()) {
tree = false;
//cerr << "Cycle found while searching for root: " << root << endl;
}
}
// Color full tree:
marked.clear();
stack<int> s;
s.push(root);
while(tree && !s.empty()) {
int node = s.top();
s.pop();
if(marked.find(node) != marked.end()) {
tree = false; // already visited!
//cerr << "Cycle found while visiting all nodes: " << node << endl;
break;
}
marked.insert(node);
if(edgeStarts.find(node) == edgeStarts.end())
continue;
int start = edgeStarts[node];
for(int i = start; i < (int)edges.size() && edges[i].first == node; ++i) {
s.push(edges[i].second);
}
}
if(tree) {
if(marked.size() != nodes.size()) {
tree = false;
//cerr << "Not all nodes visited: " << nodes.size() << " vs " << marked.size() << endl;
}
}
cout << "Case " << cas << " is ";
if(!tree)
cout << "not ";
cout << "a tree." << endl;
}
}