BZOJ4455 小星星(動態規劃,容斥)

2022-03-20 04:57:57 字數 1131 閱讀 4803

bzoj

洛谷uoj

題意說簡單點就是給定一張\(n\)個點的圖和一棵\(n\)個點的樹,現在要讓圖和樹之間的點一一對應,並且如果樹上存在一條邊,那麼圖上對應的點對之間也要存在邊。

我們直接求解顯然很麻煩,一一對應是乙個很不好算的東西。

那麼我們先要求並不需要一一對應,隨意對應即可,最後再減掉不合法的方案,這樣就可以用容斥來解決。

怎麼容斥呢?無非是考慮沒有一一對應的關係,那麼我們先暴力列舉一下哪些點在圖上可以和樹上的點進行對應,其他的點不能夠和樹上的點進行匹配。

那麼考慮\(dp\)計算方案數。

設\(f[i][j]\)表示當前以\(i\)為根的子樹(假裝以\(1\)號點為根節點的有根樹),並且\(i\)在圖上對應的點是\(j\)的方案數。

每次暴力選擇乙個和當前\(i\)匹配的點,然後再暴力找到這個點在圖中的所有兒子,並且用子樹進行轉移,這樣\(dp\)一次的複雜度是\(o(n\times n\times n)\),即樹上每個點都要做一次,要暴力列舉和哪個點進行匹配,還需要暴力列舉兒子是哪個點,當然這樣肯定不滿。

再加上暴力列舉可以進行匹配的點集的列舉,

所以總的時間複雜度是\(o(n^32^n)\)

#include#include#include#include#include#includeusing namespace std;

#define ll long long

#define max 20

inline int read()

struct linee1[max*max<<1],e2[max<<1];

int h1[max],h2[max];

int cnt1=1,cnt2=1;

int n,m,cnt,a[max];

inline void add1(int u,int v);h1[u]=cnt1++;}

inline void add2(int u,int v);h2[u]=cnt2++;}

ll f[max][max],ans=0,num;

void dfs(int u,int ff) }}

int main()

printf("%lld\n",ans);

return 0;

}

bzoj4455 容斥原理 DP 小星星

description 小y是乙個心靈手巧的女孩子,她喜歡手工製作一些小飾品。她有n顆小星星,用m條彩色的細線串了起來,每條細 線連著兩顆小星星。有一天她發現,她的飾品被破壞了,很多細線都被拆掉了。這個飾品只剩下了n?1條細線,但 通過這些細線,這顆小星星還是被串在一起,也就是這些小星星通過這些細線...

小星星 子集反演 容斥

小 y 是乙個心靈手巧的女孩子,她喜歡手工製作一些小飾品。她有 n 顆小星星,用 m 條彩色的細線串了起來,每條細線連著兩顆小星星。有一天她發現,她的飾品被破壞了,很多細線都被拆掉了。這個飾品只剩下了 n 1 條細線,但通過這些細線,這顆小星星還是被串在一起,也就是這些小星星通過這些細線形成了樹。小...

容斥 ZJOI2016 小星星

小y是乙個心靈手巧的女孩子,她喜歡手工製作一些小飾品。她有n顆小星星,用m條彩色的細線串了起來,每條細線連著兩顆小星星。有一天她發現,她的飾品被破壞了,很多細線都被拆掉了。這個飾品只剩下了n?1條細線,但通過這些細線,這顆小星星還是被串在一起,也就是這些小星星通過這些細線形成了樹。小y找到了這個飾品...