無向圖,求生成子圖(保留所有頂點,刪除部分邊)中為仙人掌的數量。仙人掌定義:連通且每條邊最多屬於一個簡單環。若原圖非仙人掌輸出 0。
邊數+1。BigInteger 高精度存儲。void tarjan(int u, int fa) {
dfn[u] = low[u] = ++idx;
for (i=head[u]; i!=-1; i=ed[i].next) {
if (ed[i].flag) continue;
ed[i].flag = ed[i^1].flag = true;
st[++top] = i;
v = ed[i].v;
if (dfn[v]==-1) {
tarjan(v, u); low[u]=min(low[u], low[v]);
if (dfn[u] <= low[v]) { // 割點/橋,彈出一塊
int num=0; do { j=st[top--]; num++; } while (i!=j);
if (num>1) num++; res = res.multiply(BigInteger.valueOf(num));
}
} else low[u]=min(low[u], dfn[v]);
if (low[v] < dfn[u]) f++; // 統計非樹邊
}
if (f > 1) res = BigInteger.ZERO; // 非仙人掌
}
BigInteger 處理。本題將「仙人掌生成子圖計數」轉化為「環邊數+1 乘積」,Tarjan 邊雙連通分量分解是核心,Java 高精度省去手寫大數乘法麻煩。