前言:一度以为这个题目是一个组合数的题,但是看完才知道是dp算的,太巧妙
要注意dp数组的初始化问题
cpp
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n, m, q, x;
const int N = (int)1e6 + 5;
int e[N*2], ne[N*2], h[N], idx = 0;
int dep[N];
int vis[N];
int ans[5005];
int dp[5005][5005];
const int Mod = (int)1e9 + 7;
void add(int a, int b) {
e[++idx] = b, ne[idx] = h[a], h[a] = idx;
}
void bfs() {
queue<int> q;
q.push(x); vis[x] = 1;
while (q.size()) {
int u = q.front(); q.pop();
for (int i = h[u]; i; i = ne[i]) {
int to = e[i];
if (vis[to]) continue;
vis[to] = 1;
dep[to] = dep[u] + 1; ans[dep[to]]++;
q.push(to);
}
}
}
signed main() {
cin >> n >> m >> q >> x;
for (int i = 1; i <= m; i++) {
int u, v; cin >> u >> v; add(u, v), add(v, u);
}
bfs();
// 似乎需要排列组合? no no
int ma = 1;
for (int i = 1; i <= 5000; i++) {
if (ans[i]) {
ma = max(ma, i);
}
else break;
}
// dp[ i ] [ j ] 表示 从距离 i 中选 j 个点
for (int i = 0; i <= ma; i++) dp[i][0] = 1;
for (int i = 1; i <= ma; i++) {
for (int j = 1; j <= i; j++) {
dp[i][j] += dp[i - 1][j];
dp[i][j] = (dp[i][j] + dp[i - 1][j - 1] * ans[i] % Mod) % Mod;
}
}
for (int i = 1; i <= q; i++) {
int k; cin >> k;
cout << dp[ma][k] << endl;
}
return 0;
}