#include <bits/stdc++.h>
using namespace std ;
#define MAXN 200
#define MOD 1000000007
typedef enum
{
NO_STANDS = 0,
SAFE_STANDS = 1,
NOT_SAFE_STANDS = 2
} state_t;
int counts[MAXN][MAXN + 1][3], aux[MAXN][MAXN + 1][3], neighbours[MAXN][MAXN], n_neighbours[MAXN];
int remove_back_edges(int v, int u)
{
int i = 0;
while (i < n_neighbours[v])
{
if (neighbours[v][i] == u)
neighbours[v][i] = neighbours[v][ -- n_neighbours[v]] ;
else
remove_back_edges(neighbours[v][i++], v);
}
}
void count_combinations(int u, int k)
{
int i, j, l, v;
for (i = 0; i < n_neighbours[u]; i++)
count_combinations(neighbours[u][i], k);
memset(aux, 0, 3 * MAXN * (MAXN + 1) * sizeof(int));
// "Base case" making the following for-loop accumulate counts.
aux[0][0][NO_STANDS] = 1;
for (i = 0; i < n_neighbours[u]; i++)
{
v = neighbours[u][i];
for (j = 0; j <= k; j++)
{
for (l = 0; l <= j; l++)
{
aux[i + 1][j][NO_STANDS] += ((long long) aux[i][j - l][NO_STANDS] * counts[v][l][NO_STANDS]) % MOD;
aux[i + 1][j][NO_STANDS] %= MOD;
aux[i + 1][j][SAFE_STANDS] += ((long long) aux[i][j - l][NO_STANDS] * counts[v][l][SAFE_STANDS]) % MOD;
aux[i + 1][j][SAFE_STANDS] %= MOD;
aux[i + 1][j][NOT_SAFE_STANDS] += ((long long) aux[i][j - l][NO_STANDS] * counts[v][l][NOT_SAFE_STANDS]) % MOD;
aux[i + 1][j][NOT_SAFE_STANDS] %= MOD;
/**************************************************/
aux[i + 1][j][SAFE_STANDS] += ((long long) aux[i][j - l][SAFE_STANDS] * counts[v][l][NO_STANDS]) % MOD;
aux[i + 1][j][SAFE_STANDS] %= MOD;
aux[i + 1][j][SAFE_STANDS] += ((long long) aux[i][j - l][SAFE_STANDS] * counts[v][l][SAFE_STANDS]) % MOD;
aux[i + 1][j][SAFE_STANDS] %= MOD;
aux[i + 1][j][NOT_SAFE_STANDS] += ((long long) aux[i][j - l][SAFE_STANDS] * counts[v][l][NOT_SAFE_STANDS]) % MOD;
aux[i + 1][j][NOT_SAFE_STANDS] %= MOD;
/**************************************************/
aux[i + 1][j][NOT_SAFE_STANDS] += ((long long) aux[i][j - l][NOT_SAFE_STANDS] * counts[v][l][NO_STANDS]) % MOD;
aux[i + 1][j][NOT_SAFE_STANDS] %= MOD;
aux[i + 1][j][NOT_SAFE_STANDS] += ((long long) aux[i][j - l][NOT_SAFE_STANDS] * counts[v][l][SAFE_STANDS]) % MOD;
aux[i + 1][j][NOT_SAFE_STANDS] %= MOD;
aux[i + 1][j][NOT_SAFE_STANDS] += ((long long) aux[i][j - l][NOT_SAFE_STANDS] * counts[v][l][NOT_SAFE_STANDS]) % MOD;
aux[i + 1][j][NOT_SAFE_STANDS] %= MOD;
}
}
}
/* Meaning behind all of this:
* ===========================
* aux[n_neighbours[u]][k][NO_STANDS] - number of ways to place `k` stands in the tree rooted at node `u`,
* where no stand is placed at `u` or at root of any of its subtrees
*
* aux[n_neighbours[u]][k][SAFE_STANDS] - number of ways to place `k` stands in the tree rooted at node `u`,
* where no stand is placed at `u` and all stands placed at roots of
* its subtrees are "safe" (they are incident to yet another stand
* down the tree)
*
* aux[n_neighbours[u]][k][NOT_SAFE_STANDS] - number of ways to place `k` stands in the tree rooted at node `u`,
* where no stand is placed at `u` and not all stands placed at the
* roots of its subtrees are "safe" (i.e. there is at least one, that
* is not incident with another stand down the tree)
*
* In case of `counts`, the enum values should be interpreted in singular.
*
* counts[u][k][NO_STANDS] - number of ways to place `k` stands in the tree rooted at node `u`,
* where no stand is placed at `u`.
*
* counts[u][k][SAFE_STANDS] - number of ways to place `k` stands in the tree rooted at node `u`,
* where a stand is placed at `u` and it is adjacent with another stand
* placed at a root of one of its subtrees (i.e. it is "safe").
*
* counts[u][k][NOT_SAFE_STANDS] - number of ways to place `k` stands in the tree rooted at node `u`,
* where a stand is placed at `u` but no stand is place at any root
* of it subtrees.
*/
// Base case (trivial solution).
counts[u][0][NO_STANDS] = 1;
for (i = 1; i <= k; i++)
{
counts[u][i][NO_STANDS] = (aux[n_neighbours[u]][i][NO_STANDS] + aux[n_neighbours[u]][i][SAFE_STANDS]) % MOD;
counts[u][i][SAFE_STANDS] = (aux[n_neighbours[u]][i - 1][SAFE_STANDS] + aux[n_neighbours[u]][i - 1][NOT_SAFE_STANDS]) % MOD;
counts[u][i][NOT_SAFE_STANDS] = aux[n_neighbours[u]][i - 1][NO_STANDS];
}
}
int solve(int k)
{
remove_back_edges(0, -1);
count_combinations(0, k);
return (counts[0][k][NO_STANDS] + counts[0][k][SAFE_STANDS]) % MOD;
}
///n_neighbours[] number of point s degree
int main()
{
int i, u, v, N, K;
while (~ scanf("%d %d", &N, &K)){
memset(n_neighbours, 0, MAXN * sizeof(int));
for (i = 0; i < N - 1; i++)
{
scanf("%d %d", &u, &v);
-- u;
-- v;
neighbours[u][n_neighbours[u]++] = v;
neighbours[v][n_neighbours[v]++] = u;
}
printf("%d\n", solve(K));
}
return 0;
}
tree standings 樹 && dp
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.