1203. 项目管理
分类:图、拓扑排序
这题不会,照着题解做的
一个组有一些任务,没有被发配组的任务假设由从m
开始递增的唯一组接手(如果不存在没有被分配组的任务,那么这些组接手的任务数量为0,总保持组的数量与任务数量相等)。由于任务与任务存在前后依赖,且同一组的任务需要排在一起。所以通过任务之间的依赖关系形成组之间的依赖关系。
故,先对组进行拓扑排序,再依次对组所拥有的任务进行拓扑排序,即为结果
class Solution {
public:
vector<int> topSort(vector<int>& degree, vector<vector<int> >& graph, vector<int>& ids){
queue<int> q;
vector<int> res;
for(int i : ids)
if(degree[i] == 0) q.push(i);
while(!q.empty()){
int cur = q.front(); q.pop(); res.push_back(cur);
for(int next : graph[cur])
if(--degree[next] == 0) q.push(next);
}
return res.size() == ids.size() ? res : vector<int>();
}
vector<int> sortItems(int n, int m, vector<int>& group, vector<vector<int>>& beforeItems) {
vector<int> res;
//组到任务的映射
vector<vector<int> > group2Item(n+m);
//初始化图
vector<vector<int> > groupGraph(n+m);
vector<vector<int> > itemGraph(n);
vector<int> groupDegree(n+m, 0);
vector<int> itemDegree(n, 0);
//给没有被分配的组分配一个不重复的组,初始化组到任务的映射
int leftGroup = m;
for(int i=0; i<n; i++){
if(group[i] == -1) group[i] = leftGroup++;
group2Item[group[i]].emplace_back(i);
}
//初始化任务的图
for(int curItem=0; curItem<beforeItems.size(); curItem++){
int curGroup = group[curItem];
for(int beforeItem : beforeItems[curItem]){
int beforeGroup = group[beforeItem];
if(curGroup==beforeGroup){ //同一组内任务的依赖关系
itemGraph[beforeItem].emplace_back(curItem);
itemDegree[curItem] += 1;
}else{ //不同组之间的依赖关系
groupGraph[beforeGroup].emplace_back(curGroup);
groupDegree[curGroup] += 1;
}
}
}
//组间拓扑排序
vector<int> groupIds(n+m); for(int i=0; i<n+m; i++) groupIds[i]=i;
vector<int> groupTopSort = topSort(groupDegree, groupGraph, groupIds);
if (groupTopSort.size() == 0) return vector<int>();
//组内拓扑排序
for(int groupId : groupTopSort){
int size = group2Item[groupId].size();
if(size == 0) continue;
vector<int> groupItemTopSort = topSort(itemDegree, itemGraph, group2Item[groupId]);
if(groupItemTopSort.size() == 0) return vector<int>();
for(int item : groupItemTopSort) res.push_back(item);
}
return res;
}
};
/* 42% */
2021/01/12