题意:一些牛仰慕另一些牛,仰慕具有传递性,问受其他所有牛仰慕的牛有多少?
思路:强连通分量,拓扑排序最后的强连通分量才可能是受其他所有牛仰慕的牛,还要反向dfs一次看是不是所有点可达,若有某个点不能到达则没有受其他所有牛仰慕的牛
思路:强连通分量,拓扑排序最后的强连通分量才可能是受其他所有牛仰慕的牛,还要反向dfs一次看是不是所有点可达,若有某个点不能到达则没有受其他所有牛仰慕的牛
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
const int maxn = 1e4 + 10;
const int INF = 1e9;
using namespace std;
vector<int> G[maxn];
vector<int> rG[maxn];
vector<int> vs;
int use[maxn], n, topo[maxn], m;
void add(int f, int t) {
G[f].push_back(t);
rG[t].push_back(f);
}
void dfs(int u) {
use[u] = 1;
for(int i = 0; i < G[u].size(); i++) {
int vv = G[u][i];
if(!use[vv]) dfs(vv);
}
vs.push_back(u);
}
void rdfs(int u, int k) {
use[u] = 1; topo[u] = k;
for(int i = 0; i < rG[u].size(); i++) {
int vv = rG[u][i];
if(!use[vv]) rdfs(vv, k);
}
}
int scc() {
int k = 1;
memset(use, 0, sizeof(use));
vs.clear();
for(int i = 1; i <= n; i++) {
if(!use[i]) dfs(i);
}
memset(use, 0, sizeof(use));
for(int i = vs.size() - 1; i >= 0; i--) {
int v = vs[i];
if(!use[v]) rdfs(v, k++);
}
return k - 1;
}
int solve() {
int nn = scc();
int u, num = 0;
for(int i = 1; i <= n; i++) {
if(topo[i] == nn) {
num++; u = i;
}
}
memset(use, 0, sizeof(use));
rdfs(u, 0);
for(int i = 1; i <= n; i++) {
if(!use[i]) return 0;
}
return num;
}
int main() {
while(scanf("%d %d", &n, &m) != EOF) {
for(int i = 0; i < maxn; i++) {
G[i].clear();
rG[i].clear();
}
while(m--) {
int from, to;
scanf("%d %d", &from, &to);
add(from, to);
}
int ans = solve();
printf("%d\n", ans);
}
return 0;
}