2020-06-09
1.题目描述
项目管理
2.题解
由于题目要求同一小组的项目,排序后在列表中彼此相邻
1.首先进行组间排序,有拓扑序列则转向2
2.其次进行组内排序,有拓扑序列则输出结果
3.代码
class Solution {
public:
vector<int> sortItems(int n, int m, vector<int>& group, vector<vector<int>>& beforeItems) {
// n个项目,m个小组
if (m==0||n==0) return vector<int>();
int grouplen=m;
for (int i=0;i<group.size();i++){ // 没有组的重新进行分组
if (group[i]==-1) group[i]=grouplen++;
}
vector<int> itemdegree(n);
vector<vector<int>> itemadjacent(n);
vector<int> groupdegree(grouplen);
vector<vector<int>> groupadjacent(grouplen);
vector<vector<int>> groupitem(grouplen);
// 进行初始化
for (int i=0;i<beforeItems.size();i++){
for (auto index:beforeItems[i]){
if (group[i]==group[index]){ // 组内的关系
itemdegree[i]++;
itemadjacent[index].push_back(i);
}
else{
if (!count(groupadjacent[group[index]].begin(),groupadjacent[group[index]].end(),group[i])){
groupdegree[group[i]]++;
groupadjacent[group[index]].push_back(group[i]);
}
}
}
}
for (int i=0;i<group.size();i++){
groupitem[group[i]].push_back(i);
}
vector<int> vec;
// 先处理组间关系
queue<int> que1;
int cnt1=0;
for (int i=0;i<grouplen;i++){
if (!groupdegree[i]){ // 入度为0
que1.push(i);
vec.push_back(i);
cnt1++;
}
}
while (!que1.empty()){
int tmp=que1.front();
que1.pop();
for (auto value:groupadjacent[tmp]){
groupdegree[value]--;
if (!groupdegree[value]){
que1.push(value);
vec.push_back(value);
cnt1++;
}
}
}
// 组间关系不满足条件
if (cnt1!=grouplen) return vector<int>();
vector<int> res;
// 再处理组内关系
for (int i=0;i<grouplen;i++){
int groupindex=vec[i]; // 先处理第groupindex组
queue<int> que2;
int cnt2=0;
for (auto value:groupitem[groupindex]){
if (!itemdegree[value]){
que2.push(value);
res.push_back(value);
cnt2++;
}
}
while (!que2.empty()){
int tmp=que2.front();
que2.pop();
for (auto value:itemadjacent[tmp]){
itemdegree[value]--;
if (!itemdegree[value]){
que2.push(value);
res.push_back(value);
cnt2++;
}
}
}
if (cnt2!=groupitem[groupindex].size()) return vector<int>();
}
return res;
}
};