传送门:牛客
题目描述:
Trees also play an intimate role in many of the world's mythologies. Many scholars are interested in finding peculiar properties about trees, such as the center of a tree, tree counting, tree coloring. A(x) is one of such properties.
A(x) (accumulation degree of node x) is defined as follows:
Each edge of the tree has an positive capacity.
The nodes with degree of one in the tree are named terminals.
The flow of each edge can't exceed its capacity.
A(x) is the maximal flow that node x can flow to other terminal nodes.
Since it may be hard to understand the definition, an example is showed below:
输入:
1
5
1 2 11
1 4 13
3 4 5
4 5 10
输出:
26
一道经典的换根dp的题目.
主要思路:
至此,我们的换根dp结束了
下面是具体的代码部分:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define root 1,n,1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {
ll x=0,w=1;char ch=getchar();
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x*w;
}
#define maxn 1000000
#define ll_maxn 0x3f3f3f3f3f3f3f3f
const double eps=1e-8;
#define int ll
int min(int a,int b) {return a>b?b:a;}
int n,k;
int dp[2500][2500];
vector<int>tree[3000];
int ans=0;
const int mod=998244353;int size_tree[maxn];
void dfs(int u,int pre_u) {
dp[u][1]=1;size_tree[u]=1;
for(int i=0;i<tree[u].size();i++) {
int v=tree[u][i];
if(v==pre_u) continue;
dfs(v,u);int sum=0;
for(int j=1;j<=min(size_tree[v],k);j++) {//记录删边时子树的情况
sum=(sum+dp[v][j])%mod;
}
for(int vu=min(size_tree[u],k);vu>=1;vu--) {
for(int vv=min(size_tree[v],k);vv>=1;vv--) {
if(vv+vu<=k) dp[u][vv+vu]=(dp[u][vu+vv]+dp[u][vu]*dp[v][vv]%mod)%mod;
}
dp[u][vu]=dp[u][vu]*sum%mod;
}
size_tree[u]+=size_tree[v];
}
return ;
}
signed main() {
n=read();k=read();int u,v;
for(int i=1;i<n;i++) {
u=read();v=read();
tree[u].push_back(v);
tree[v].push_back(u);
}
dfs(1,0);
for(int i=1;i<=k;i++) {
ans=(ans+dp[1][i])%mod;
}
cout<<ans<<endl;
return 0;
}