forked from mpfeifer1/Kattis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchesstournament.cpp
137 lines (114 loc) · 2.63 KB
/
chesstournament.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <unordered_map>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct query {
int l, r;
char op;
};
int find(vector<int>& disjoint, int a) {
if(disjoint[a] == -1) {
return a;
}
int tmp = find(disjoint, disjoint[a]);
disjoint[a] = tmp;
return tmp;
}
void join(vector<int>& disjoint, int a, int b) {
a = find(disjoint, a);
b = find(disjoint, b);
if(a == b) {
return;
}
disjoint[b] = a;
}
int main() {
// Fast I/O
ios::sync_with_stdio(false);
cin.tie(NULL);
int n, m;
cin >> n >> m;
// Read in all the queries
vector<query> equal;
vector<query> compare;
for(int i = 0; i < m; i++) {
query q;
cin >> q.l >> q.op >> q.r;
if(q.op == '=') {
equal.push_back(q);
}
else {
compare.push_back(q);
}
}
// Build disjoint set of players
vector<int> disjoint(n, -1);
for(int i = 0; i < equal.size(); i++) {
join(disjoint, equal[i].l, equal[i].r);
}
// Make easy conversions between actual and index
unordered_map<int, int> ActualToIdx;
int size = 0;
for(unsigned int i = 0; i < disjoint.size(); i++) {
int actual = find(disjoint, i);
if(ActualToIdx.count(actual) == 0) {
ActualToIdx[actual] = size;
size++;
}
}
// Build adjacency matrix
vector<vector<int>> adj;
adj.resize(size);
// Run queries
for(auto i : compare) {
int x = ActualToIdx[find(disjoint, i.l)];
int y = ActualToIdx[find(disjoint, i.r)];
adj[x].push_back(y);
}
// Prepare the Topo Sort
queue<int> zeroin;
int current = 0;
int count = 0;
// Calculate Indegrees
vector<int> indegree(size);
for(auto i : adj) {
for(auto j : i) {
indegree[j]++;
}
}
// Add players to queue
for(int i = 0; i < size; i++) {
if(indegree[i] == 0) {
zeroin.push(i);
}
}
// Run the Topo Sort
while(!zeroin.empty()) {
/*
if(zeroin.size() > 1) {
cout << "inconsistent" << endl;
return 0;
}
*/
current = zeroin.front();
zeroin.pop();
for(auto j : adj[current]) {
indegree[j]--;
if(indegree[j] == 0) {
zeroin.push(j);
}
}
count++;
}
// Get the results
if(count != size) {
cout << "inconsistent" << endl;
return 0;
}
else {
cout << "consistent" << endl;
return 0;
}
}