思路:
两次拓扑排序:先对小组进行拓扑排序,确定不同小组之间的先后顺序,再分别对各个小组的项目进行拓扑排序,确定组内项目的先后顺序。
实现:
1 class Solution 2 { 3 public: 4 inline vector<int> toposort_item(vector<int>& group_res, vector<unordered_set<int>>& gvc, 5 vector<vector<int>>& G) 6 { 7 int n = G.size(); 8 vector<int> ind(n, 0); 9 for (int i = 0; i < n; i++) 10 { 11 for (int j = 0; j < G[i].size(); j++) 12 { 13 int s = G[i][j]; ind[s]++; 14 } 15 } 16 queue<int> q; 17 vector<int> res; 18 for (int i = 0; i < group_res.size(); i++) 19 { 20 vector<int> tmp; 21 for (auto& it: gvc[group_res[i]]) 22 { 23 if (ind[it] == 0) q.push(it); 24 } 25 while (!q.empty()) 26 { 27 int t = q.front(); q.pop(); 28 tmp.push_back(t); 29 for (int i = 0; i < G[t].size(); i++) 30 { 31 int s = G[t][i]; ind[s]--; 32 if (ind[s] == 0) q.push(s); 33 } 34 } 35 if (tmp.size() != gvc[group_res[i]].size()) return vector<int>(); 36 res.insert(res.end(), tmp.begin(), tmp.end()); 37 } 38 return res; 39 } 40 vector<int> toposort_group(vector<vector<int>>& G) 41 { 42 int m = G.size(); 43 vector<int> ind(m, 0); 44 for (int i = 0; i < m; i++) 45 { 46 for (int j = 0; j < G[i].size(); j++) 47 { 48 int s = G[i][j]; ind[s]++; 49 } 50 } 51 queue<int> q; 52 for (int i = 0; i < m; i++) 53 { 54 if (ind[i] == 0) q.push(i); 55 } 56 vector<int> res; 57 while (!q.empty()) 58 { 59 int t = q.front(); q.pop(); 60 res.push_back(t); 61 for (int i = 0; i < G[t].size(); i++) 62 { 63 int s = G[t][i]; ind[s]--; 64 if (ind[s] == 0) q.push(s); 65 } 66 } 67 if (res.size() != m) return vector<int>(); 68 return res; 69 } 70 vector<int> sortItems(int n, int m, vector<int>& group, vector<vector<int>>& beforeItems) 71 { 72 for (int i = 0; i < n; i++) 73 { 74 if (group[i] == -1) group[i] = m++; 75 } 76 vector<unordered_set<int>> gvc(m, unordered_set<int>()); 77 for (int i = 0; i < n; i++) 78 { 79 gvc[group[i]].insert(i); 80 } 81 vector<vector<int>> among(m, vector<int>()), within(n, vector<int>()); 82 for (int i = 0; i < beforeItems.size(); i++) 83 { 84 for (int j = 0; j < beforeItems[i].size(); j++) 85 { 86 int t = beforeItems[i][j]; 87 int x = group[i], y = group[t]; 88 if (x != y) among[y].push_back(x); 89 else within[t].push_back(i); 90 } 91 } 92 vector<int> tmp = toposort_group(among); 93 if (tmp.empty()) return tmp; 94 vector<int> res = toposort_item(tmp, gvc, within); 95 return res; 96 } 97 };