給定一張n個點m條邊的有向無環圖,分別統計從每個點出發能夠到達的點的數量。
輸入格式
第一行兩個整數n,m,接下來m行每行兩個整數x,y,表示從x到y的一條有向邊。
輸出格式
輸出共n行,表示每個點能夠到達的點的數量。
資料範圍
1<=n,m<=30000
輸入樣例:
10 10
3 82 3
2 55 9
5 92 3
3 94 8
2 10
4 9輸出樣例:16
3321
1111
題解 :拓撲排序適用於有向無環圖(dag),我們用拓撲排序對所有點進行排序,我們可以得到乙個有順序的序列(不是大小順序,是優先順序 )。
這樣我們倒著列舉,排完序的序列最後乙個數肯定出度為0,也就是只能自己指向自己,向前遍歷,前乙個數是基於他能夠到達的後乙個數決定的。
問題來了,我們如何計算呢,題目中給的記憶體空間為256m,如果我們開乙個30000 * 30000的二維陣列,1e6大約4m ,這個二維陣列3600m炸記憶體了。
我們可以利用bitset函式進行位運算,bitset<30000> f[30000] f【i】代表每乙個點,第二維代表是乙個01串(二進位制),int型可以代表32個二進位制數(0代表到不了,1代表可以到),所以空間大約為(30000 * 30000)/(32 ) 約等於 120m (√)
二進位制位運算可以避免重複 0 1得1 , 1 1 得1
前面的方案數由後面的方案書累加起來。
最後bitset可以直接輸出這個01串中的1的個數
#include
#include
#include
#include
#include
#include
using
namespace std;
typedef
long
long ll;
const
int maxn=
30010
;vector vec[maxn]
;bitset f[maxn]
;ll top[maxn]
=,indeg[maxn]=;
ll n,m;
void
topsort()
while
(q.size()
)}}int
main()
topsort()
;for
(int i=n;i>=
1;i--)}
for(
int i=
1;i<=n;i++
)return0;
}
AcWing 164 可達性統計
給定一張n個點m條邊的有向無環圖,分別統計從每個點出發能夠到達的點的數量。輸入格式 第一行兩個整數n,m,接下來m行每行兩個整數x,y,表示從x到y的一條有向邊。輸出格式 輸出共n行,表示每個點能夠到達的點的數量。資料範圍1 n,m 30000 1 n,m 30000 顯然可以用拓撲排序 狀態壓縮來...
AcWing 164 可達性統計 搜尋
圖的遍歷 原題鏈結 本題思路 建立乙個圖的鄰接表 每個煉表裡都儲存了與之直連的點,那判斷乙個點的可達性,可求那些直連點自己煉表裡儲存點的並集 優化方案與技巧 bitset 將數壓縮為二進位制形式 內部表現 的十進位制 外部表現 陣列模擬鄰接表int e n ne n h n idx void add...
可達性統計
題目描述 給定一張n個點m條邊的有向無環圖,分別統計從每個點出發能夠到達的點的數量。n,m 30000。輸入第一行兩個整數n,m,接下來m行每行兩個整數x,y,表示從x到y的一條有向邊。輸出共n行,表示每個點能夠到達的點的數量。樣例輸入 複製樣例資料 10 10 3 82 3 2 55 9 5 92...