这题考点是强联通分量的知识点,大致思路就是tarjan缩点后,判断新图中出度为0的点的数量。这里有个小坑,就是在建图那块,应该建反向边,具体看题目
实现代码:
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
const int N = 210;
int n;
int dfn[N], low[N], tot;
int scc[N], dout[N], cnt, isinst[N];
vector<int> e[N], ne[N];
stack<int> stk;
void tarjan(int x) {
dfn[x] = low[x] = ++tot;
stk.push(x); isinst[x] = 1;
for(int y : e[x]) {
if(!dfn[y]) {
tarjan(y);
low[x] = min(low[x], low[y]);
} else if(isinst[y]) {
low[x] = min(low[x], dfn[y]);
}
}
if(dfn[x] == low[x]) {
cnt++;
while(1) {
int y = stk.top(); stk.pop(); isinst[y] = 0;
scc[y] = cnt;
if(y == x) break;
}
}
}
int main() {
cin >> n;
for(int i = 1; i <= n; i++) {
int x; cin >> x;
while(x != 0) {
e[x].push_back(i); //看清题目表述,应该反向建边
cin >> x;
}
}
for(int i = 1; i <= n; i++)
if(!dfn[i]) tarjan(i);
for(int i = 1; i <= n; i++) {
for(int j : e[i]) {
if(scc[j] != scc[i]) {
dout[scc[i]]++;
}
}
}
int mx = 0;
for(int i = 1; i <= cnt; i++) {
if(!dout[i]) mx++;
}
cout << mx;
return 0;
}
后序题目会继续上传