164. 可达性统计 拓扑排序 逆拓扑序求路径点数 长二进制数 bitset的运用 位运算

43 篇文章 1 订阅

题目

在这里插入图片描述

题解思路

先获取图形的拓扑序,再反着走一遍拓扑序(加上反向建边),利用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 ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值