1. 程式人生 > 其它 >題解 Yet Another NPC Problem

題解 Yet Another NPC Problem

Description

Solution

以下純屬口胡,並沒有寫。

考慮對於一個圖,如果存在兩個點使得它們不包含對方的連出點集不同,那麼我交換兩者的編號還是一個合法圖,那麼就會抵消掉,所以我們只需要考慮任意兩個點不包含對方的連出點集都相同的情況。

對於連出點集相同的情況,如果兩者沒有連邊,那麼我選最大團一定只能選其中一個,否則我們可以兩個都選。

所以我們可以考慮合併,我們設 \(s(u)\) 表示 \(u\) 表示的點集選出的最大團大小。那麼上述情況中如果 \(u,v\) 存在邊,那麼 \(s(u)\to s(u)+s(v)\),否則 \(s(u)\to \max(s(u),s(v))\) ,然後將 \(u,v\)

合併。為了方便,\(u,v\) 沒有邊的時候只有 \(s(u)=s(v)\) 的時候我們才合併,可以看出一個點代表的點集連出子集都相同。

可以發現我們合併完的圖,一定 \(s\) 都是 \(2^i\) 形式,且不會存在 \(s\) 相同的情況。因為如果存在相同的情況,二者連出點集一定相同,一定可以繼續合併,否則貢獻為 \(0\)。所以對於我們一個狀態我們就可以用 \(b\in (0,n]\) 表示。

我們考慮設 \(f(n,b)\) 表示 \(n\) 個點的圖縮成狀態 \(b\) 的方案數,\(g(b,m)\) 表示狀態為 \(b\) 的最大團剛好為 \(m\) 的方案數。

那麼答案就是:

\[\sum_{k=0}^{l-1} \sum_{b}^{n} f(m+k,b)\times g(b,m) \]

考慮如何求解 \(g(b,m)\)

的值,可以發現 \(g(b,m)=[m=b\vee m=b-\text{low}(b)]\)

首先 \(m=b\vee m=b-\text{low}(b)]\) 一定有值。考慮其他情況,我們假設 \(y\) 是狀態從大到小第一個沒有選的,\(x\) 是選的最小值狀態。因為 \(m\) 確定那麼我們選的點就確定了。那麼 \(y\) 是否與 \(x\) 相連都可以。因為如果 \(y\) 與其他點除 \(x\) 外都相連,那麼我們選 \(y\) 一定最大團比 \(m\) 大,所以 \(y\) 一定不與其他點出 \(x\) 外都相連。

考慮我們如何求得 \(f(n,b)\) 的值。我們可以考慮在 \(n-1\)

個點的基礎上加入一個點。你考慮合併過程,如果是一路合併沒遇到 \(s\) 相同,那麼會產生的 \(b\) 貢獻就是 \(1\),那麼就是 \(f(n-1,b-1)\),如果是一路合併然後 \(s\) 相同,那麼一定是 \(\text{low}(b)\) 被合併到,貢獻就是 \(f(n-1,b+\text{low}(b)-1)\)

至此,我們得到了 \(\Theta(m\times (m+l))\) 的演算法。