1. 拓扑排序选课
题意
现在你总共有 n
门课需要选,记为 0
到 n-1
。在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0
,你需要先完成课程 1
,我们用一个匹配来表示他们,如: 0,1
。给定课程总量,条件条数以及它们的先决条件,判断是否可能完成所有课程的学习?
2. 判断有向图是否是简单无环图
题意
判断一个有向图是否是简单无环图。
分析
拓扑排序裸题,但要注意,判断是否成环时,需要统计节点压入队列的次数,如果不等于总节点数,便成环。
#include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
const int MAXN = 1e5;
int n, m, H[MAXN], tot = 0, InD[MAXN];
struct Edge{
int to, nextNbr = -1;
} E[MAXN << 1];
queue<int> myque;
void addEdge(int u, int v){
tot++;
E[tot].to = v;
E[tot].nextNbr = H[u];
H[u] = tot;
}
bool ToSort(){
int cnt = 0;
for (int i = 0; i < n; i++){
if(InD[i] == 0){
myque.push(i);
cnt++;
}
}
while(!myque.empty()){
int v = myque.front();
myque.pop();
for (int i = H[v]; i >= 0; i = E[i].nextNbr){
int u = E[i].to;
InD[u]--;
if(InD[u] == 0){
myque.push(u);
cnt++;
}
}
}
return cnt == n ? true : false;
}
int main(){
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) H[i] = -1;
for (int i = 1; i <= m; i++) {
int tmpu, tmpv;
scanf("%d,%d", &tmpu, &tmpv);
addEdge(tmpu, tmpv);
InD[tmpv]++;
}
bool f = ToSort();
}