[leetcode]1462. 课程表 IV

题目链接

题意

给定n个课程 ,一个二维数组grid,grid[0]grid[1]的先修课程
先修课程具有传递性
如果课程 a 是课程 b 的先决条件,课程 b 是课程 c 的先决条件,那么课程 a 就是课程 c 的决条件

q次询问 给出一个queries数组 返回每个询问是true/false 以数组形式返回

思路

显然拓扑排序
数据范围 n < = 100 n<=100 n<=100
可以开一个二维数组 bool st[N][N];
st[i][j]=1表示ij的先修课程
这样查询的时候只需要 O ( 1 ) O(1) O(1)

Code

class Solution {
public:
    vector<bool> checkIfPrerequisite(int n, vector<vector<int>>& grid, vector<vector<int>>& queries) {
        vector<vector<int>>g(n);
        vector<int>d(n);
        for(auto e:grid){
            int a=e[0],b=e[1];
            g[a].emplace_back(b);
            d[b]++;
        }
        
        vector<int>q(n);
        int hh=0,tt=-1;
        vector<vector<bool>>st(n,vector<bool>(n));

        auto topsort=[&]()->bool{
            for(int i=0;i<n;i++){
                if(d[i]==0) q[++tt]=i;
            }

            while(hh<=tt){
                int t=q[hh++];

                for(int i:g[t]){
                    st[t][i]=1;
                    for(int j=0;j<n;j++){
                        // st[j][i]|=st[j][t];这样写会报错 我也不知道为啥
                        st[j][i]=st[j][i]|st[j][t];//关键部分
                    }
                    if(--d[i]==0){
                        q[++tt]=i;
                    }
                }
            }
            return tt==n-1;
        };
        topsort();
        
        vector<bool>ret;
        for(auto e:queries){
            int a=e[0],b=e[1];
            ret.push_back(st[a][b]);
        }
    
        return ret;
    }
};

实现细节

关键看st的递推更新
每次取出队头

for(int i:g[t]){
    st[t][i]=1;//i是t的邻接点,t必然是i的先修课程
    for(int j=0;j<n;j++){//遍历所有点 
        // st[j][i]|=st[j][t];
        st[j][i]=st[j][i]|st[j][t];//如果j是t的先修课程 那么j一定是i的先修课程
    }
    if(--d[i]==0){
        q[++tt]=i;
    }
}           
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值