Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <vector>
- #include <stack>
- #include <set>
- #include <stdlib.h>
- #include <algorithm>
- using namespace std;
- void go(int curr, const vector<string> &names, const vector<vector<bool>> &relations, vector<int> &used, bool *visited,
- bool transposed) {
- // printf("in %d\n", curr + 1);
- visited[curr] = true;
- vector<int> children;
- for (int i = 0; i < relations.size(); ++i) {
- bool arrow = transposed ? relations[i][curr] : relations[curr][i];
- if (arrow && !visited[i])
- children.push_back(i);
- }
- // sort children by name
- sort(children.begin(), children.end(), [names](int a, int b) {
- return names[a] < names[b];
- });
- for (int child : children) {
- if (!visited[child])
- go(child, names, relations, used, visited, transposed);
- }
- used.push_back(curr);
- // printf("after %d\n", curr + 1);
- }
- vector<vector<string>> getList(vector<string> &names, vector<vector<bool>> &relations) {
- // setlocale(LC_ALL, "rus");
- // find sources of graph
- vector<int> sources;
- for (int i = 0; i < relations.size(); ++i) {
- // has incoming edges
- bool hasIns = false;
- for (int j = 0; j < relations.size(); ++j) {
- // check column i
- if (relations[j][i]) {
- hasIns = true;
- break;
- }
- }
- if (!hasIns)
- sources.push_back(i);
- }
- // printf("sources:\n");
- // for (auto &&source : sources) {
- // printf("%d %s\n",source + 1, names[source].c_str());
- // }
- // sort sources by name
- sort(sources.begin(), sources.end(), [names](int a, int b) {
- return names[a] < names[b];
- });
- bool *visited = new bool[relations.size()];
- for (int i = 0; i < relations.size(); ++i) {
- visited[i] = false;
- }
- // nodes, sorted by post-value
- vector<int> used;
- for (int source : sources) {
- go(source, names, relations, used, visited, false);
- }
- reverse(used.begin(), used.end());
- // reset visited
- for (int i = 0; i < relations.size(); ++i) {
- visited[i] = false;
- }
- vector<vector<string>> ans;
- // iterate in reversed post-value order
- for (int node : used) {
- if (visited[node])
- continue;
- vector<int> intGroup;
- go(node, names, relations, intGroup, visited, true);
- vector<string> stringGroup;
- for (int elInGroup : intGroup) {
- stringGroup.push_back(names[elInGroup]);
- }
- // sort inside one group
- sort(stringGroup.begin(), stringGroup.end());
- ans.push_back(stringGroup);
- }
- // sort groups by first name
- sort(ans.begin(), ans.end(), [](vector<string>& a, vector<string>& b) {
- return a.front() < b.front();
- });
- delete[] visited;
- return ans;
- }
- int main() {
- vector<string> names = vector<string>();
- vector<vector<bool>> relations;
- int startIndex;
- ifstream fin;
- fin.open("input.txt");
- if (fin.is_open()) {
- string str = "";
- getline(fin, str);
- while (str != "#") {
- names.emplace_back(str.substr(str.find(' ') + 1));
- getline(fin, str);
- }
- relations = vector<vector<bool>>(names.size());
- for (int i = 0; i < names.size(); i++) {
- relations[i] = vector<bool>(names.size());
- for (int j = 0; j < names.size(); j++)
- relations[i][j] = false;
- }
- getline(fin, str);
- while (fin) {
- int a = stoi(str.substr(0, str.find(' '))) - 1;
- int b = stoi(str.substr(str.find(' '))) - 1;
- relations[a][b] = true;
- getline(fin, str);
- }
- fin.close();
- }
- vector<vector<string>> res = getList(names, relations);
- fstream fout;
- fout.open("output.txt", ios::out);
- for (int i = 0; i < res.size(); i++) {
- for (int j = 0; j < res[i].size(); j++)
- fout << res[i][j] << "\n";
- fout << "\n";
- }
- fout.close();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement