[zjoi2017]仙人掌
前言
謹(jǐn)以此題紀(jì)念我第一次參加省選時(shí)剛了5h這一題得到0分的經(jīng)歷
題目相關(guān)
鏈接
題目大意
給出仙人掌定義:如果一個(gè)無自環(huán)無重邊無向連通圖的任意一條邊最多屬于一個(gè)簡單環(huán),我們就稱之為仙人掌
給出一個(gè)圖,求有多少種加邊方式使得圖成為一個(gè)仙人掌
數(shù)據(jù)范圍
多組數(shù)據(jù)
∑n≤5?105,∑m≤106\sum n\le5*10^5,\sum m\le10^6∑n≤5?105,∑m≤106
題解
首先,如果這幅圖本身就已經(jīng)不是仙人掌了,那么輸出000
如何判斷呢?我們發(fā)現(xiàn),建圓方樹的時(shí)候,兩條圓點(diǎn)的連邊最多只會(huì)被刪除一次,如果被刪除了多次那么說明這幅圖不是仙人掌
對(duì)于仙人掌的簡單環(huán)上的邊,我們一定不可以進(jìn)行一條連邊使得兩個(gè)端點(diǎn)之間有一條路徑經(jīng)過這條邊(因?yàn)檫@樣就會(huì)出現(xiàn)一條邊在多個(gè)簡單環(huán)中的情況)
那么我們就直接把仙人掌簡單環(huán)上的邊直接刪除,容易發(fā)現(xiàn)剩下的都是一些樹了
對(duì)于樹的情況,我們發(fā)現(xiàn)有兩個(gè)東西不好處理:一個(gè)是最終的圖中可以有邊不在簡單環(huán)上,二是添加的邊不能有重邊
我們發(fā)現(xiàn)這兩個(gè)問題合在一起就被解決了,我們可以轉(zhuǎn)化成:每條邊都必須要在一個(gè)簡單環(huán)上,允許有重邊。容易發(fā)現(xiàn),這么轉(zhuǎn)化的答案不變
現(xiàn)在相當(dāng)于是對(duì)于一棵樹,求其被鏈覆蓋的方案數(shù)
考慮樹形dp
我們定義fif_ifi?為以iii節(jié)點(diǎn)所在子樹及其通往父親的邊被鏈覆蓋的方案數(shù)
設(shè)sonuson_usonu?為uuu節(jié)點(diǎn)的兒子集合,S(n)S(n)S(n)為nnn個(gè)點(diǎn)、每個(gè)點(diǎn)的度數(shù)小于等于111的圖的數(shù)量
我們發(fā)現(xiàn)fu=S(∣sonu∣+1)?∏v∈sonufvf_u=S(|son_u|+1)*\prod_{v\in son_u}f_vfu?=S(∣sonu?∣+1)?v∈sonu?∏?fv?
特殊的,我們發(fā)現(xiàn)根節(jié)點(diǎn)沒有父親邊,這樣的話其fif_ifi?的定義不包含通往父親的邊,那么S(x)S(x)S(x)里面的xxx就是兒子數(shù)量了
我們現(xiàn)在考慮怎么求S(n)S(n)S(n)
我們考慮已知S(1)S(1)S(1)~S(n)S(n)S(n),怎么求S(n+1)S(n+1)S(n+1)
我們考慮第n+1n+1n+1個(gè)點(diǎn)
如果它不連邊,那么方案數(shù)為S(n)S(n)S(n)
如果它連邊,在前面nnn個(gè)點(diǎn)中選擇一個(gè)連,那么方案數(shù)就為S(n?1)?nS(n-1)*nS(n?1)?n
即得到遞推式S(n+1)=S(n)+n?S(n?1)S(n+1)=S(n)+n*S(n-1)S(n+1)=S(n)+n?S(n?1)
這樣,我們就能O(n)\mathcal O(n)O(n)的完成此題
代碼
#include<cstdio> #include<cctype> #include<algorithm> #include<cstring> namespace fast_IO {const int IN_LEN=1000000,OUT_LEN=1000000;char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1;inline char getchar_(){return (ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;}inline void putchar_(const char x){if(oh==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;*oh++=x;}inline void flush(){fwrite(obuf,1,oh-obuf,stdout);} } using namespace fast_IO; #define getchar() getchar_() #define putchar(x) putchar_((x)) #define rg register typedef long long ll; template<typename T>inline void read(T&x){char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;} template<typename T>inline void printe(const T x){if(x>=10)printe(x/10);putchar(x%10+'0');} template<typename T>inline void print(const T x){if(x>=0)printe(x);else putchar('-'),printe(-x);} template <typename T> inline T min(const T a,const T b){return a<b?a:b;} template <typename T> inline T abs(const T a){return a>0?a:-a;} const int maxn=500005,maxm=2000005,mod=998244353; int T,n,m; int head[maxn],nxt[maxm],tow[maxm],tmp;bool del[maxm],DIE,VVV[maxm],vis[maxn]; inline void addb(const int u,const int v) {tmp++;nxt[tmp]=head[u];head[u]=tmp;tow[tmp]=v;del[tmp]=VVV[tmp>>1]=0; } int stack[maxn],top,H; void dfs(const int u) {if(DIE)return;vis[u]=1;for(rg int i=head[u];i&&!DIE;i=nxt[i])if(!VVV[i>>1]){VVV[i>>1]=1;const int v=tow[i];stack[++top]=i;if(vis[v]){H=top;for(rg int j=top-1;j&&tow[stack[j]]!=v;j--)H=j;for(rg int j=top;j>=H;j--){const int id=stack[j];if(del[id])DIE=1;del[id]=del[id^1]=1;}}else dfs(v);top--;} } ll S[maxn],f[maxn],ans; void DFS(const int u,const int fa) {int size=0;f[u]=1,vis[u]=1;for(rg int i=head[u];i;i=nxt[i])if(!del[i]){const int v=tow[i];if(v!=fa)DFS(v,u),f[u]=f[u]*f[v]%mod,size++;}if(fa)size++;f[u]=f[u]*S[size]%mod; } int main() {S[0]=S[1]=1;for(rg int i=2;i<=500000;i++)S[i]=(S[i-1]+S[i-2]*(i-1))%mod;read(T);while(T--){tmp=1;read(n),read(m);top=0;for(rg int i=1;i<=m;i++){int u,v;read(u),read(v);addb(u,v),addb(v,u);}DIE=0,dfs(1);if(DIE)ans=0;else{ans=1;for(rg int i=1;i<=n;i++)vis[i]=0;for(rg int i=1;i<=n;i++)if(!vis[i]){int d=0;for(rg int j=head[i];j;j=nxt[j])if(!del[j])d++;if(d==1){DFS(i,0);ans=ans*f[i]%mod;}}}print(ans),putchar('\n');for(rg int i=1;i<=n;i++)head[i]=0,vis[i]=0;}return flush(),0; }總結(jié)
其實(shí)和仙人掌沒啥關(guān)系,就是很清真的樹形dp,被題目名勸退了
然后轉(zhuǎn)化問題的思路比較巧妙
最后,祈禱今年浙江省選RP++吧
總結(jié)
以上是生活随笔為你收集整理的[zjoi2017]仙人掌的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [luogu4128][shoi2006
- 下一篇: 动态dp