Advertisement
IzhanVarsky

Untitled

May 4th, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.96 KB | None | 0 0
  1. //#include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <queue>
  5. #include <set>
  6. #include <map>
  7.  
  8. using namespace std;
  9.  
  10. struct Triple {
  11. int from, to;
  12. char sym;
  13.  
  14. Triple(int from, int to, char sym) :
  15. from(from), to(to), sym(sym) {}
  16. };
  17.  
  18. const int N = 50001;
  19. const int M = 26;
  20. int n, m, k;
  21. bool isTermin[N];
  22. int aut[N][M];
  23. int nums[N];
  24. int used[N];
  25. vector<vector<vector<int>>> Inv(N, vector<vector<int>>(M, vector<int>()));
  26. vector<vector<int>> new_pereh(N, vector<int>(M, -1));
  27. vector<Triple> min_aut;
  28. int new_sost_cnt = 0;
  29. int Class[N];
  30.  
  31. void set_used(int v = 1) {
  32. if (v == 0) return;
  33. used[v] = true;
  34. for (int i = 0; i < M; ++i) {
  35. if (!used[aut[v][i]]) {
  36. set_used(aut[v][i]);
  37. }
  38. }
  39. }
  40.  
  41. void findEquivalenceClasses() {
  42. set<int> F;
  43. set<int> NF;
  44. vector<set<int>> P;
  45. queue<pair<int, int>> Q;
  46. for (int i = 0; i < n; ++i) {
  47. if (isTermin[i]) {
  48. F.insert(i);
  49. Class[i] = 0;
  50. } else {
  51. NF.insert(i);
  52. Class[i] = 1;
  53. }
  54. }
  55. P.push_back(F);
  56. P.push_back(NF);
  57. for (int i = 0; i < M; ++i) {
  58. Q.push({0, i});
  59. Q.push({1, i});
  60. }
  61. while (!Q.empty()) {
  62. auto C = P[Q.front().first];
  63. auto a = Q.front().second;
  64. Q.pop();
  65. map<int, vector<int>> Involved;
  66. for (auto q : C) {
  67. for (auto v : Inv[q][a]) {
  68. Involved[Class[v]].push_back(v);
  69. }
  70. }
  71. for (const auto& p : Involved) {
  72. if (!p.second.empty()) {
  73. auto i = p.first;
  74. if (Involved[i].size() < P[i].size()) {
  75. int j = P.size();
  76. P.emplace_back();
  77. for (auto v : Involved[i]) {
  78. P[i].erase(v);
  79. P[j].insert(v);
  80. }
  81. if (P[i].size() < P[j].size()) {
  82. swap(P[i], P[j]);
  83. }
  84. for (auto r : P[j]) {
  85. Class[r] = j;
  86. }
  87. for (int z = 0; z < M; ++z) {
  88. Q.push({j, z});
  89. }
  90. }
  91. }
  92. }
  93. }
  94. }
  95.  
  96. void set_min_aut(int v) {
  97. if (nums[v] == 0) {
  98. nums[v] = ++new_sost_cnt;
  99. for (int i = 0; i < M; ++i) {
  100. if (new_pereh[v][i] != -1) {
  101. set_min_aut(new_pereh[v][i]);
  102. min_aut.emplace_back(nums[v], nums[new_pereh[v][i]], i + 'a');
  103. }
  104. }
  105. }
  106. }
  107.  
  108. int main() {
  109. ifstream cin("minimization.in");
  110. ofstream cout("minimization.out");
  111. cin >> n >> m >> k;
  112. n++;
  113. int a, b;
  114. char c;
  115. for (int i = 0; i < k; ++i) {
  116. cin >> a;
  117. isTermin[a] = true;
  118. }
  119. for (int i = 0; i < m; ++i) {
  120. cin >> a >> b >> c;
  121. aut[a][c - 'a'] = b;
  122. }
  123. for (int i = 0; i < n; i++) {
  124. for (int j = 0; j < M; j++) {
  125. Inv[aut[i][j]][j].push_back(i);
  126. }
  127. }
  128. set_used();
  129. findEquivalenceClasses();
  130. for (int i = 0; i < n; ++i) {
  131. if (Class[i] != Class[0] && used[i]) {
  132. for (int j = 0; j < M; ++j) {
  133. if (Class[aut[i][j]] != Class[0] && used[aut[i][j]]) {
  134. new_pereh[Class[i]][j] = Class[aut[i][j]];
  135. }
  136. }
  137. }
  138. }
  139. set_min_aut(Class[1]);
  140. set<int> new_isTermin;
  141. for (int i = 1; i < n; i++) {
  142. if (isTermin[i] && Class[i] != Class[0] && used[i]) {
  143. new_isTermin.insert(nums[Class[i]]);
  144. }
  145. }
  146. cout << new_sost_cnt << " " << min_aut.size() << " " << new_isTermin.size() << endl;
  147. for (int t : new_isTermin) {
  148. cout << t << " ";
  149. }
  150. cout << endl;
  151. for (auto x : min_aut) {
  152. cout << x.from << " " << x.to << " " << x.sym << endl;
  153. }
  154. return 0;
  155. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement