我们可以发现,转移都是从当前点能到达的点转移而来,但是拓扑是正向的,所以我们建立反边即可。
代码很短,只有18行
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e4+10;
int n,m,dag[N]; vector<int> g[N]; bitset<N> dp[N];
signed main(){
cin>>n>>m;
for(int i=1,x,y;i<=m;i++) cin>>x>>y,dag[x]++,g[y].push_back(x);
queue<int> q; for(int i=1;i<=n;i++) if(!dag[i]) q.push(i);
while(q.size()){
int u=q.front(); q.pop(); dp[u][u]=1;
for(int i=0;i<g[u].size();i++){
int to=g[u][i]; dp[to]|=dp[u];
if(--dag[to]==0) q.push(to);
}
}
for(int i=1;i<=n;i++) cout<<dp[i].count()<<'\n';
return 0;
}
不应该是dag[y]++吗 是x-> y