I implemented a fairly straightforward soln for this problem that is very similar to the editorial in essense. It uses bitsets and the main logic goes as follows:
As all ancestors for a node (lets say node a) are known when the node is first created, we can determine the nodes "b" for which a and b could form the middle part of a diamond. Whenever a new class is created, I first check if any pair of ancestors for the new class form such a couple (I denote below as "hate[][]"). If so this would create a diamond and we can terminate our search.
Otherwise I will proceed to calculate new such pairs having the new node as "a". I believe the impl is not too incomprehensible but I will be happy to answer questions. This code gets 27 points so I dont believe anything is wrong with the parsing. here is my submission code: ~~~~~
include <bits/stdc++.h>
define int long long
define pii pair<int,int>
define vi vector
define ff first
define ss second
define all(x) x.begin(),x.end()
define sp << " " <<
using namespace std;
const int N =1e5+10,MOD = 1e9+7,inf = 2e9;
void solve() { int n; cin >> n; int nd = 0; bitset<1001> go[1001],come[1001],hate[1001],share; string trash; getline(cin,trash); map<string,int> mp; for (int i = 1;i<=n;i++) { string name,realname; getline(cin,name); string cur; int start = 0; vi pars; bool fl = 1; for (int j = 0;j<name.size();j++) { if (name[j] == ':') start = 1; if (!start && name[j] >= 'a' && name[j] <= 'z') realname+=name[j]; if (start && name[j] >= 'a' && name[j] <= 'z') cur+=name[j]; else { if (!cur.empty()) { if (!mp.count(cur)) { fl = 0; break; } pars.push_back(mp[cur]); } cur.clear(); } } if (!fl || mp[realname]) { cout << "greska" << endl; continue; } ++nd; come[nd].set(nd); go[nd].set(nd); for (auto it : pars) come[nd]|=come[it]; for (int j = 1;j<nd && fl;j++) { if (!come[nd][j]) continue; for (int jj = j+1;jj<nd && fl;jj++) { if (come[nd][jj] && hate[j][jj]) { fl = 0; break; } } } if (!fl) { come[nd].reset(); go[nd].reset(); --nd; cout << "greska" << endl; continue; } cout << "ok" << endl; for (int j = 1;j<nd;j++) { if (come[nd][j]) go[j][nd] = 1; } mp[realname] = nd; //cout << realname << " IS " << nd << '\n'; share.reset(); for (int j = 1;j<nd;j++){ if (come[nd][j]) { share|=go[j]; } } for (int j = 1;j<nd;j++) { if (share[j] && !go[j][nd]) { hate[nd][j] = hate[j][nd] = 1; } } } }
signed main() { ios_base::sync_with_stdio(0);cin.tie(0); #ifdef Dodi freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif int t = 1; //cin >> t; while (t --> 0) solve(); } ~~~~~



