1500
蘋果曼和樹
基準時間限制:1 秒 空間限制:131072 kb 分值: 80 難度:5
級演算法題
收藏
關注
蘋果曼有一棵
n個點的樹。有一些(至少乙個)結點被標記為黑色,有一些結點被標記為白色。
現在考慮乙個包含
k(0 ≤ k < n)
條樹邊的集合。如果蘋果曼刪除這些邊,那麼會將這個樹分成
(k+1)
個部分。每個部分還是一棵樹。
現在蘋果曼想知道有多少種邊的集合,可以使得刪除之後每乙個部分恰好包含乙個黑色結點。答案對
1000000007
取餘即可。
input
單組測試資料。
第一行有乙個整數
n (2 ≤ n ≤ 10^5)
,表示樹中結點的數目。
第二行有
n-1個整數
p[0],p[1],...,p[n-2] (0 ≤ p[i] ≤ i)
。表示p[i]
和(i+1)
之間有一條邊。結點從
0開始編號。
第三行給出每個結點的顏色,包含
n個整數
x[0],x[1],...,x[n-1] (x[i]是0
或者1)
。如果x[i]是1
,那麼第
i個點就是黑色的,否則是白色的。
output
輸出答案佔一行。
input示例
3
0 0
0 1 1
output示例
2
system message
(題目提供者)
c++
的執行時限為:1000 ms ,空間限制為:131072 kb
題解:本道題是樹形dp一類題目(方案樹)的通用解題方法,就是考慮每個節點與其兒子節點的合法關係更具乘法原理統計方案。對於題目的條件,可以簡化問題:將給定的樹分為k個聯通塊,每個聯通塊有且僅有乙個黑點。抓住關鍵條件:有且僅有乙個黑點,
那麼對於每個節點,就用dp【i】表示以i為根節點的子樹中刪邊後i所在的聯通塊沒有黑點的方案數,dp【i】表示以i為根節點的子樹中刪完邊後i所在的聯通塊有乙個黑點的方案數。
分情況討論:
i為黑點:對於兒子節點son,若son所在的聯通塊有乙個黑點,那就斷開i與son的邊,方案數為dp【i】*dp【son】;若son所在的聯通塊沒有黑點,那就保留i與son的邊,方案數為dp【i】*dp【son】(dp的巧妙在於沒有討論刪邊,直接討論點與點的情況)。所以i為黑點的dp【i】點總方案數為:dp【i】=(dp【i】*(dp【son】+dp【son】));那麼dp【i】喃,很顯然,因為i為黑點,dp【i】點值永遠為0不必討論。
i為白點:對於兒子son,若son所在的聯通塊沒有黑點可以保留也可以刪邊,對於son所在的聯通塊有乙個黑點,則刪邊。所以dp【i】=dp【i】*(dp【son】+dp【son】);因為每個聯通塊至少要有乙個黑點。所以dp【i】=(dp【i】*(dp【son】+dp【son】)+dp【i】*dp【son】)
總結:做樹形dp的題一定要弄清楚關係,兒子與父親的關係,有時更行關係並不僅限於父親和兒子,還有可能是兒子與祖先。對於題目中的一些操作(此題中的刪邊),當很難列舉和表示時,通常可以通過表示其他狀態來間接表示這些操作,畢竟操作就是改變狀態。樹形dp中的方案數問題通常都要用到乘法原理。
#include #include #include #include #define n 300000
#define mod 1000000007
using namespace std;
int n;
int last[n<<1],to[n<<1],head[n],cnt=0;
int v[n];
long long dp[n][3];
void ins(int u,int v)
void dfs(int x,int fa)
}int main()
{// freopen("in.txt","r",stdin);
memset(head,-1,sizeof(head));
int tmp;
scanf("%d",&n);
for(int i=0;i
51nod 1500 蘋果曼和樹(樹形dp)
題目 思路 分析狀態間的關係 dp u 1 0 代表與u相連的聯通塊是否具有黑點的方案數 注意有刪邊 dp u 1 當u相連的聯通塊具有黑點時,兒子結點v具有黑點與否都可以 當u相連的聯通塊不具有黑點時,兒子結點必須具有黑點 dp u 0 u相連的聯通塊肯定不具有黑點,兒子結點具有黑點與否都可以 i...
51 Nod 1500 蘋果曼和樹(樹形dp)
思路 樹形dp。我們考慮當前結點 i 對於結點 i 它可以屬於它的子樹,也可以不屬於,換句話說,我們可以計算出與 i 結點相連的連通塊中是否具有黑點的方案數。於是,d i 表示包含 i 的連通塊中含有黑點,d i 表示不含有。接下來考慮狀態轉移方程 上面的只是我個人認為的。可能是錯的哈 1 incl...
51nod1502 蘋果曼和紙
蘋果曼有很大的一張紙。這張紙的形狀是1 n的長方形。你的任務是幫助蘋果曼來摺疊這一張紙。有一些操作,這些操作有如下兩個種形式 1.把這張紙在第pi個位置對折。經過對折後,左邊的1 pi部分會蓋到右邊的1 當前紙片寬度 pi 上面。2.詢問在如果把距離左端li以內的剪掉,距離左端ri以外的也剪掉,那麼...