【JZOJ】【暴力】樹

LinkLink

JZOJ 2753JZOJ\ 2753

DescriptionDescription

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

InputInput

第一行是兩個整數N和S,其中N是樹的節點數。

第二行是N個正整數,第i個整數表示節點i的正整數。

接下來的N-1行每行是2個整數x和y,表示y是x的兒子。

OutputOutput

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

SampleSample InputInput

3 3
1 2 3
1 2
1 3

SampleSample OutputOutput

2

HintHint

對於30%數據,N≤100;

對於60%數據,N≤1000;

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

TrainTrain ofof ThoughtThought

一開始想了很多種奇妙的方法,最後發現自己都無法很完美地實現,最後無奈之下打個暴力想騙分,結果A了!(數據過水?)

CodeCode

#include<iostream>
#include<cstring>
#include<cstdio>

using namespace std;

int N, t;
int havefa[100005], h[100005], A[100005];
long long Ans, S;

struct node
{
	int to, next;
}F[100005];

void dfs(int x, long long dep)
{
	dep += A[x];//一直疊加路徑總值
	if (dep == S) {
		Ans++;
		return;
	}//達到了就給路徑數加上
	else if (dep > S) return;//如果超過了目標值也就沒有繼續搜下去的必要了
	else {
		for (int i = h[x]; i; i = F[i].next)
			dfs(F[i].to, dep);	
	}
}

int main()
{
	scanf("%d%lld", &N, &S);
	for (int i = 1; i <= N; ++i) 
		scanf("%d", &A[i]);
	for (int i = 1; i < N; ++i)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		F[++t] = (node){y, h[x]}; h[x] = t; 
		havefa[y] = 1;
	} 
	for (int i = 1; i <= N; ++i) dfs(i, 0);
    printf("%lld", Ans);
    return 0;
}  
發佈了224 篇原創文章 · 獲贊 35 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章