小C的島嶼 題解

2022-09-10 20:18:21 字數 2666 閱讀 4131

ioi2018 集訓隊作業 by 任軒笛

小c有\(n\)個島嶼。她為了管理島上的人,決定讓這些島嶼連通。

每個島嶼i有乙個概率值\(p_i\),和乙個友好列表\(a_i\)。

小c首先來到了1號島嶼,她會依次執行下面操作:

設現在在島嶼\(x\),有\(p_x\)的概率產生一條無向邊連線兩個隨機島嶼,這兩個島嶼不會相同,也不會已經有邊相連。(即在尚不存在的無向邊中隨機一條加入圖中,不會加自環)

如果此時所有島嶼連通,她就會心滿意足地離開。

否則她會在當前點的友好列表中,等概率選擇乙個,走到那座島嶼上。她的不滿意度會+1,並重複第1步。

求小c的期望不滿意度,答案模1000000007。

設 \(f[x][m]\) 表示現在在 \(x\) 節點, 已經加入了 \(m\) 條邊, 圖還未聯通, 不滿意度的期望; 顯然 \(f[1][0]\) 就是答案.

設 \(g[m]\) 表示當前有 \(m\) 條邊且圖沒有聯通, 並且加入原圖中不存在的一條邊後聯通的概率.

\[f[x][m]=\frac\sum_(f[k][m+1]+1)+\frac\sum_(f[k][m]+1)

\]發現這個式子可以分層高斯消元, 複雜度 \(o(n^5)\).

現在看如何求 \(g[m]\), 設 \(a_\) 表示 \(n\) 個點 \(m\) 條邊的無向圖方案數, \(b_\) 表示 \(n\) 個點 \(m\) 條邊聯通無向圖方案數:

\[g[m]=\frac^\binom\sum_^b_b_i(n-i)}-b_)\times (\binom-m)}

\]顯然, \(a_=\binom}\). 現在考慮如何求 \(b_\): 這是乙個經典問題, 可以做到 \(o(n^4)\). 但是由於這道題要對所有的 \((n,m)\) 都要求, 所以還是 \(o(n^5)\) 的. 但是問題不大

考慮將整個圖分成若干子集, 使得不同子集間不能有邊, 同一子集中不做要求. 設 \(h(k)\) 表示將整個圖分成 \(k\) 個子集的方案數, 那麼含有 \(x\) 個聯通塊的方案會被恰好算到 \(s(x,k)\) 次, 其中 \(s\) 是第二類斯特林數.

考慮到 \(\sum_^s(n,i)(-1)^(i-1)!=[n=1]\). 那麼我們將所有的 \(h(k)\) 乘上 \((-1)^(k-1)!\) 再求和, 得到的就是只有乙個聯通塊的方案數.

於是考慮設 \(h[i][j]\) 表示用了 \(i\) 個點, \(j\) 條邊的方案數. 由於需要湊出 \((-1)^(k-1)!\) 的係數, 可以在轉移的時候列舉任意乙個點的聯通塊(而不是1號點所在的聯通塊)進行轉移, 這樣就可以帶上 \(k!\) 的係數, 最後再用一次列舉 1 號點聯通塊的轉移即可. 最終求 \(b_\) 的時候還要乘上 \(\binom\) 的係數, 因為轉移的時候對於每個子集內部是作完全圖來考慮的.

**:

#include #define n 55

#define m 2555

using namespace std;

const int mod = 1e9 + 7;

inline int fsp(int x, int k = mod - 2)

return res;

}inline void inc(int &x, long long y)

int n, m, p[n], a[n][n], b[n][m], c[m][m];

int f[n][m], g[m], h[n][m];

vectors[n];

inline int a(int x, int y)

void gauss()

}for (int i = n; i >= 1; --i)

}int main()

for (int i = 0; i <= m; ++i)

for (int j = c[i][0] = 1; j <= i; ++j)

c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;

h[0][0] = 1;

for (int i = 1; i <= n; ++i)

for (int j = 0; j <= c[i][2]; ++j)

for (int k = 1; k <= i && c[k][2] <= j; ++k)

inc(h[i][j], mod - 1ll * h[i - k][j - c[k][2]] * c[i][k] % mod);

for (int i = n; i >= 1; --i)

for (int j = c[i][2]; j >= 0; --j)

for (int i = 1; i <= n; ++i)

for (int j = 0; j <= m; ++j)

for (int k = j; k <= m; ++k)

inc(b[i][j], 1ll * h[i][k] * c[k][j]);

for (int i = 0, u, v; i <= m; ++i)

for (int j = m; j >= 0; --j)

}gauss();

for (int k = 1; k <= n; ++k)

f[k][j] = a[k][k];

}return cout << f[1][0] << endl, 0;

}

島嶼問題系列題解

給你乙個由 1 陸地 和 0 水 組成的的二維網格,島嶼總是被水包圍,並且每座島嶼只能由水平方向和 或豎直方向上相鄰的陸地連線形成。此外,你可以假設該網格的四條邊均被水包圍。求島嶼的數量。輸入 11110 11010 11000 00000 輸出 1 輸入 11000 11000 00100 000...

leetcode題解200 島嶼數量

給你乙個由 1 陸地 和 0 水 組成的的二維網格,請你計算網格中島嶼的數量。島嶼總是被水包圍,並且每座島嶼只能由水平方向和 或豎直方向上相鄰的陸地連線形成。此外,你可以假設該網格的四條邊均被水包圍。示例 1 輸入 grid 1 1 1 1 0 1 1 0 1 0 1 1 0 0 0 0 0 0 0...

島嶼周長(C )

描述 用乙個n m的二維陣列表示地圖,1表示陸地,0代表海水,每一格都表示乙個1 1的區域。地圖中的格仔只能橫向或者縱向連線 不能對角連線 連線在一起的陸地稱作島嶼,同時整個地圖都被海水圍繞。假設給出的地圖中只會有乙個島嶼,並且島嶼中不會有湖 即不會有水被陸地包圍的情況出現 請判斷所給定的二維地圖中...