閉包傳遞
阿新 • • 發佈:2020-11-27
https://ac.nowcoder.com/acm/contest/1013/A
題面
給定一張N個點M條邊的有向無環圖,分別統計從每個點出發能夠到達的點的數量。\(N,M\leq 30000\)
分析
用\(bitset\)維護每個點的閉包
時間複雜度\(O(\frac{n\times n}{30})\)
\(\therefore\) 30000級別很有可能是閉包(\(lg^4\))
bitset
bitset操作:
- 呼叫一位:s[]
- 二進位制操作:^|&
- 判斷是否相等:== !=
- 設1: s.set();
- 設0:s.reset();
- 統計1個數:s.count();
#include<bits/stdc++.h> using namespace std; const int N=3e4+5; int n,m,to[N],nxt[N],he[N],cnt; bool fl[N]; bitset<N>b[N]; inline void add(int u,int v) { to[++cnt]=v,nxt[cnt]=he[u],he[u]=cnt; } void dfs(int u) { if(fl[u]) return; fl[u]=1; b[u][u]=1; for(int e=he[u];e;e=nxt[e]) { int v=to[e]; dfs(v); b[u]|=b[v]; } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v); } for(int i=1;i<=n;i++) { if(!fl[i]) { dfs(i); } printf("%d\n",(int)b[i].count()); } return 0; }