Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #include <iostream>
- using namespace std;
- vector<set<int>> links; //Предки и дети чисел
- vector<set<int>> ans; //Распределение по группам
- set<int> cur; //Набор чисел с которыми я работаю
- bool changed = true;
- bool *added;
- void addRelatives(int num)
- {
- if (added[num])
- return;
- added[num] = true;
- int ind = 0, indchild = 1;
- if (ans[1].count(num))
- {
- ind = 1;
- indchild = 2;
- }
- else if (ans[2].count(num))
- {
- ind = 2;
- indchild = 0;
- }
- for (auto i : links[num])
- {
- if (cur.count(i))
- cur.erase(cur.find(i));
- ans[indchild].insert(i);
- addRelatives(i);
- }
- changed = true;
- }
- void descrPos(int num)
- {
- for (auto i : links[num])
- {
- if (ans[0].count(i))
- {
- ans[2].insert(num);
- cur.erase(cur.find(num));
- addRelatives(num);
- return;
- }
- else if (ans[1].count(i))
- {
- ans[0].insert(num);
- cur.erase(cur.find(num));
- addRelatives(num);
- return;
- }
- else if (ans[2].count(i))
- {
- ans[1].insert(num);
- cur.erase(cur.find(num));
- addRelatives(num);
- return;
- }
- }
- }
- void tryToChange()
- {
- set<int>::iterator it = cur.begin();
- int e = *it;
- cur.erase(cur.begin());
- ans[0].insert(e);
- addRelatives(e);
- }
- bool proof()
- {
- for (int i = 0; i < links.size(); i++)
- {
- int ind = 0, indchild = 1;
- if (ans[1].count(i))
- {
- ind = 1;
- indchild = 2;
- }
- else if (ans[2].count(i))
- {
- ind = 2;
- indchild = 0;
- }
- for (auto elem : links[i])
- {
- if (!ans[indchild].count(elem))
- {
- return true;
- }
- }
- }
- return false;
- }
- signed main()
- {
- int n, m;
- ans = vector<set<int>>(3, set<int>());
- cin >> n >> m;
- bool used[n];
- added = new bool[n];
- links = vector<set<int>>();
- for (int i = 0; i < n; i++)
- {
- set<int> s;
- links.push_back(s);
- used[i] = false;
- added[i] = false;
- }
- int x, y;
- for (int i = 0; i < m; i++)
- {
- cin >> x >> y;
- x--;
- y--;
- if (x == y)
- {
- cout << "NO" << endl;
- return 0;
- }
- links[x].insert(y); //Добавляю ребенка
- cur.insert(x);
- used[x] = true;
- used[y] = true;
- }
- for (int i = 0; i < n; i++)
- {
- if (!used[i])
- {
- ans[0].insert(i);
- }
- }
- if (cur.size() > 0)
- tryToChange();
- int count, e;
- while (changed)
- {
- changed = false;
- count = cur.size();
- for (int i = 0; i < count; i++)
- {
- set<int>::iterator it = cur.begin();
- e = *it;
- descrPos(e);
- }
- if (cur.size() > 0 && !changed)
- tryToChange();
- }
- if (proof())
- {
- cout << "NO" << endl;
- }
- else
- {
- cout << "YES" << endl;
- for (int i = 0; i < 3; i++)
- {
- cout << ans[i].size() << " ";
- for (auto elem : ans[i])
- {
- cout << elem + 1 << " ";
- }
- cout << endl;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement