日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

洛谷P3252 [JLOI2012]树

發布時間:2023/11/27 生活经验 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷P3252 [JLOI2012]树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

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

輸入輸出格式

輸入格式:

?

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

?

輸出格式:

?

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

?

輸入輸出樣例

輸入樣例#1:
3 3
1 2 3
1 2
1 3
輸出樣例#1:
2

說明

對于100%數據,N<=100000,所有權值以及S都不超過1000。

?

題目大意:求樹上連續一段深度遞增的路徑的點權和為s的條數

題解:dfs(i)以i為起點的路徑有多少條?

錯因:理解錯了 不能用記憶化搜索

數據水暴力可過

代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#define LL long long
#define maxn 100008
using namespace std;int n,s,sumedge;
int head[maxn],w[maxn];
long long ans;struct Edge{int x,y,nxt;Edge(int x=0,int y=0,int nxt=0):x(x),y(y),nxt(nxt){}
}edge[maxn];void add(int x,int y){edge[++sumedge]=Edge(x,y,head[x]);head[x]=sumedge;
}LL dfs(int x,int sum){if(sum>s)return 0;if(sum==s)return 1;long long js=0;for(int i=head[x];i;i=edge[i].nxt){int v=edge[i].y;js+=dfs(v,sum+w[v]);}return js;
}int main(){scanf("%d%d",&n,&s);for(int i=1;i<=n;i++)scanf("%d",&w[i]);for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);add(x,y);}for(int i=1;i<=n;i++)if(w[i]==s)ans++;else ans+=dfs(i,w[i]);cout<<ans<<endl;return 0;
}

樹上前綴和

保存搜到i之前的祖先,累加權值,是否sum[i]-sum[祖先]=s,注意搜完時刪掉祖先。

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 100008
#define LL long long
using namespace std;int n,s,sumedge,cnt,js;
int head[maxn],w[maxn],dad[maxn],fa[maxn],sum[maxn];
LL ans;struct Edge{int x,y,nxt;Edge(int x=0,int y=0,int nxt=0):x(x),y(y),nxt(nxt){}
}edge[maxn];void add(int x,int y){edge[++sumedge]=Edge(x,y,head[x]);head[x]=sumedge;
}void dfs(int x){dad[++js]=x;for(int i=head[x];i;i=edge[i].nxt){int v=edge[i].y;sum[v]=sum[x]+w[v];for(int j=js;j>=0;j--){//要循環到0,可能它自己的點權就是s if(sum[v]-sum[dad[j]]==s)ans++;if(sum[v]-sum[dad[j]]>s)break;}dfs(v);}js--;
}int main(){scanf("%d%d",&n,&s);for(int i=1;i<=n;i++)scanf("%d",&w[i]);for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);fa[y]=x;add(x,y);}sum[1]=w[1]; dfs(1);cout<<ans<<endl;return 0;
}

?

轉載于:https://www.cnblogs.com/zzyh/p/7593079.html

總結

以上是生活随笔為你收集整理的洛谷P3252 [JLOI2012]树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。