题意
给定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
表示i
是j
的先修课程
这样查询的时候只需要
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;
}
}