我們先看看怎麼在時間內找出一個會贏的人
入度為$0$的點嗎?不是,如果整張圖是一個環就GG了
入度為$0$的$SCC$ ($Strongly\ Connected\ Component$) 嗎?
對了,就是它!
可以發現,位於同一個$SCC$內的點,不是全部有可能當冠軍,就是全部不可能當冠軍
因此,我們只須找出哪些$SCC$有可能直接或間接打敗所有其他$SCC$
先不管時間複雜度,我們來構造一個算法找出所有答案
先讓那些入度為$0$的$SCC$加入$queue$裡面,並標記為答案
然後,每次從$queue$弄出一個可能當冠軍的$SCC$ (稱作$u$)
枚舉還沒被標記答案的$SCC$ (稱作$nxt$),只要發現$nxt$可以打敗$u$ (換句話說,$(從u連到nxt的邊數)<(u的大小)*(nxt的大小)$,也就是$u$無法壓倒性勝利$nxt$),那麼$nxt$也可以當冠軍了!
把所有變成新冠軍的$SCC$加入$queue$裡面,並標記為答案
於是我們有了一個$O(N^{2})$的作法
真的是$O(N^{2})$嗎?
跟你說,如果你把還沒被標記答案的$SCC$用$set$來維護
傳上去就$AC$了
然後就會想問為甚麼
為甚麼?
可以發現,在枚舉還沒被標記答案的$SCC$時,只有兩種情況:
1. 當冠軍,從$set$中移除並加入$queue$
2. 被壓倒性勝利惹QAQ,繼續待在$set$裡面
時間複雜度取決於情況2.會發生多少次
可以發現,情況2.發生的次數不會超過圖上邊的數量 (想一想,為甚麼XD) (提示:要壓倒性勝利代表至少有一條從$u$連向$nxt$的邊)
時間複雜度:$O((N+M)+(N\log N+M))$ ($M$是邊數)
code: