BFS+DP

先按照到达x节点的距离 ,将所有节点进行分类,求出每一类的节点的数量,用cnt数组存储;

然后对cnt数组进行 dp , dp[ i ][ j ] 视作 当最大距离为 i 时,选取 j 个点,有多少种方案,

则dp[ i ][ j ] = dp[ i-1 ][ j ] + dp[ i-1 ][ j-1 ]*cnt[ i ] , 即考虑 选距离为i 的节点 和 不选距离为 i 的节点的方案和;

另外 j = 0 时 dp[ i ][ j ] 恒为 1;

#include <bits/stdc++.h>
using namespace std;
#define dbg(x) cout<<#x<<": "<<(x)<<endl;
#define int long long
#define print(x) cout<<#x<<": ";for(auto _:x)cout<<_<<' ';cout<<endl;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl '\n'
const int MOD=1e9+7;
const int N=5000;

vector<int> bfs(vector<vector<int> >&adj, int x ){
    vector<int> ret;
    vector<int> vis(adj.size());
    queue<int> q;
    q.emplace(x);
    vis[x]=true;
    while(!q.empty()){
        int sz=q.size();
        ret.emplace_back(sz);
        for(int k=1;k<=sz;k++){
            int u=q.front();q.pop();
            for(auto v:adj[u]){
                if(vis[v])continue;
                q.emplace(v);vis[v]=true;
            }
        }
    }
    return ret;
}
void solve(){
    int n,m,q,x;cin>>n>>m>>q>>x;
    vector<vector<int> > adj(n+1);
    for(int i=1;i<=m;i++){
        int u,v;cin>>u>>v;
        adj[u].emplace_back(v);
        adj[v].emplace_back(u);
    }
    vector<int> cnt=bfs(adj,x);
  
    vector<vector<int> > f(cnt.size(),vector<int>(N+1,0));
    for(int i=0;i<cnt.size();i++)f[i][0]=1;
    for(int i=1;i<cnt.size();i++){
        for(int j=1;j<=N;j++){
            (f[i][j]=f[i-1][j]+cnt[i]*f[i-1][j-1]%MOD)%=MOD;
        }
    }
  
    for(int i=1;i<=q;i++){
        int k;cin>>k;
        cout<<f[cnt.size()-1][k]<<endl;
    }
}
signed main() {
    IOS
    solve();
    return 0;
}
// 64 位输出请用 printf("%lld")