项目管理

公司共有 n n n 个项目和 m m m 个小组,每个项目要不无人接手,要不就由 m m m 个小组之一负责。

g r o u p [ i ] group[i] group[i] 表示第 i i i 个项目所属的小组,如果这个项目目前无人接手,那么 g r o u p [ i ] group[i] group[i] 就等于 − 1 -1 1。(项目和小组都是从零开始编号的)小组可能存在没有接手任何项目的情况。

请你帮忙按要求安排这些项目的进度,并返回排序后的项目列表:

同一小组的项目,排序后在列表中彼此相邻。
项目之间存在一定的依赖关系,我们用一个列表 b e f o r e I t e m s beforeItems beforeItems 来表示,其中 b e f o r e I t e m s [ i ] beforeItems[i] beforeItems[i] 表示在进行第 i i i 个项目前(位于第 i i i 个项目左侧)应该完成的所有项目。
如果存在多个解决方案,只需要返回其中任意一个即可。如果没有合适的解决方案,就请返回一个 空列表 。

示例 1:
在这里插入图片描述

输入:n = 8, m = 2, group = [-1,-1,1,0,0,1,0,-1], beforeItems = [[],[6],[5],[6],[3,6],[],[],[]]
输出:[6,3,4,1,5,2,0,7]

示例 2:

输入:n = 8, m = 2, group = [-1,-1,1,0,0,1,0,-1], beforeItems = [[],[6],[5],[6],[3],[],[4],[]]
输出:[]

解释:与示例 1 大致相同,但是在排序后的列表中,4 必须放在 6 的前面。

提示:

1 < = m < = n < = 3 ∗ 1 0 4 g r o u p . l e n g t h = = b e f o r e I t e m s . l e n g t h = = n − 1 < = g r o u p [ i ] < = m − 1 0 < = b e f o r e I t e m s [ i ] . l e n g t h < = n − 1 0 < = b e f o r e I t e m s [ i ] [ j ] < = n − 1 i ! = b e f o r e I t e m s [ i ] [ j ] 1 <= m <= n <= 3 * 10^4\\ group.length == beforeItems.length == n\\ -1 <= group[i] <= m - 1\\ 0 <= beforeItems[i].length <= n - 1\\ 0 <= beforeItems[i][j] <= n - 1\\ i != beforeItems[i][j] 1<=m<=n<=3104group.length==beforeItems.length==n1<=group[i]<=m10<=beforeItems[i].length<=n10<=beforeItems[i][j]<=n1i!=beforeItems[i][j]
b e f o r e I t e m s [ i ] beforeItems[i] beforeItems[i] 不含重复元素

class Solution {
public:

    vector<int>topo(vector<vector<int>>&graph,vector<int>&degree,vector<int>&id){
        vector<int>res;
        queue<int>q;
        for (auto &it:id){
            if (degree[it]==0){
                q.push(it);
            }
        }
        while (!q.empty()){
            int u=q.front();
            q.pop();
            res.emplace_back(u);
            for (auto &v:graph[u]){
                if (--degree[v]==0){
                    q.push(v);
                }
            }
        }
        return res.size()==id.size()?res:vector<int>{};
    }

    vector<int> sortItems(int n, int m, vector<int>& group, vector<vector<int>>& beforeItems) {
        vector<vector<int> >groupItems(n+m);

        vector<int>id;
        for (int i=0;i<n+m;i++) {
            id.emplace_back(i);
        }

        int numid=m;
        for (int i=0;i<n;i++){
            if (group[i]==-1){
                group[i]=numid;
                numid++;
            }
            groupItems[group[i]].emplace_back(i);
        }
        vector<vector<int>> groupin(n);
        vector<int>groupindegree(n,0);

        vector<vector<int>> groupout(n+m);
        vector<int>groupoutdegree(n+m,0);

        for (int i=0;i<n;i++){
            int now=group[i];
            for (auto &it:beforeItems[i]){
                int pre=group[it];
                if (now==pre){
                    groupin[it].emplace_back(i);
                    groupindegree[i]++;
                }else{
                    groupout[pre].emplace_back(now);
                    groupoutdegree[now]++;
                }
            }
        }

        vector<int>resgroutout = topo(groupout,groupoutdegree,id);
        if (resgroutout.size()==0) return vector<int>{};

        vector<int>res;
        for (auto&it:resgroutout){
            if (groupItems[it].size()==0) continue;
            vector<int>resgroutin = topo(groupin,groupindegree,groupItems[it]);
            if (resgroutin.size()==0) return vector<int>{};
            for (auto &it1:resgroutin){
                res.emplace_back(it1);
            }
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值