【JLOI2012】【BZOJ2783】樹

來源:互聯網
上載者:User

標籤:stl   set   

Description
在這個問題中,給定一個值S和一棵樹。在樹的每個節點有一個正整數,問有多少條路徑的節點總和達到S。路徑中節點的深度必須是升序的。假設節點1是根節點,根的深度是0,它的兒子節點的深度為1。路徑不必一定從根節點開始。
Input

   第一行是兩個整數N和S,其中N是樹的節點數。   第二行是N個正整數,第i個整數表示節點i的正整數。   接下來的N-1行每行是2個整數x和y,表示y是x的兒子。

Output

   輸出路徑節點總和為S的路徑數量。

Sample Input

3 3

1 2 3

1 2

1 3

Sample Output

2
HINT

對於100%資料,N≤100000,所有權值以及S都不超過1000。

由於路徑必須是深到淺的一條鏈
所以DFS+set維護出現過的值就行了

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<set>#define MAXN 100010using namespace std;int n,s,top;int val[MAXN],dis[MAXN],fa[MAXN];int root;long long ans;multiset<int> S;struct edge{    int to;    edge *next;}e[MAXN<<1],*prev[MAXN];void insert(int u,int v){    e[++top].to=v;e[top].next=prev[u];prev[u]=&e[top];}void dfs(int x){    for (edge *i=prev[x];i;i=i->next)    {        dis[i->to]=dis[x]+val[i->to];        S.insert(dis[i->to]);        if (S.find(dis[i->to]-s)!=S.end())  ans++;        dfs(i->to);        S.erase(dis[i->to]);    }}int main(){    scanf("%d%d",&n,&s);S.clear();    for (int i=1;i<=n;i++)  scanf("%d",&val[i]);    for (int i=1;i<n;i++)    {        int x,y;        scanf("%d%d",&x,&y);        fa[y]=x;insert(x,y);    }    for (int i=1;i<=n;i++)        if (!fa[i]) root=i;    dis[root]=val[root];S.insert(0);S.insert(val[root]);    if (S.find(dis[root]-s)!=S.end())   ans++;    dfs(root);    printf("%lld\n",ans);}

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

【JLOI2012】【BZOJ2783】樹

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.