题目
题解思路
先获取图形的拓扑序,再反着走一遍拓扑序(加上反向建边),利用STL里面的bitset来表示这个点和其他点的状态1则连通0不连通。
初始化自己为1。
延申一个节点的时候就和这个点的bitset值进行或运算 | (即传递1)
最后输出每个节点的bitset的含1数即可。
bitset简单介绍
这题如果用dfs来遍历的话,感觉会很复杂(因为初始节点未知,加上重边的影响)。
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
#include <bitset>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 30010 ;
int a[N] ;
vector <int> head[N] ;
vector <int> tail[N] ;
bitset <N> f[N] ;
int main ()
{
ios::sync_with_stdio(false);cin.tie(0);
int n , m ;
cin >> n >> m ;
for (int i = 1 ; i <= m ; i++ )
{
int t1 , t2 ;
cin >> t1 >> t2 ;
head[t1].push_back(t2) ;
tail[t2].push_back(t1) ;
a[t2]++ ;
}
queue <int> q ;
for (int i = 1 ; i <= n ; i++ )
{
if ( a[i] == 0 )
q.push(i) ;
}
vector <int> topsort ;
while ( ! q.empty() )
{
int tmp = q.front() ;
q.pop();
topsort.push_back(tmp) ;
for (int i = 0 ; i < head[tmp].size() ; i++ )
{
a[ head[tmp][i] ] -- ;
if ( a[ head[tmp][i] ] == 0 )
{
q.push( head[tmp][i] ) ;
}
}
}
for (int i = topsort.size()-1 ; i >= 0 ; i-- )
{
int p = topsort[i] ;
f[p][p] = 1 ;
for ( int j = 0 ; j < tail[p].size() ; j++ )
{
f[ tail[p][j] ] |= f[p] ;
}
}
for (int i = 1 ; i <= n ; i++ )
cout << f[i].count() << "\n" ;
return 0 ;
}