组合数?dp!

前言:一度以为这个题目是一个组合数的题,但是看完才知道是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;
}
相关推荐
C++ 老炮儿的技术栈3 小时前
UDP 与 TCP 的区别是什么?
开发语言·c++·windows·算法·visual studio
殇者知忧3 小时前
【论文笔记】若干矿井粉尘检测算法概述
深度学习·神经网络·算法·随机森林·机器学习·支持向量机·计算机视觉
mochensage5 小时前
C++信息学竞赛中常用函数的一般用法
java·c++·算法
chengooooooo5 小时前
leetcode Top100 238. 除自身以外数组的乘积|数组系列
算法·leetcode
GUIQU.5 小时前
【每日一题 | 2025年6.2 ~ 6.8】第16届蓝桥杯部分偏简单题
算法·蓝桥杯·每日一题
weixin_527550406 小时前
初级程序员入门指南
javascript·python·算法
嘉陵妹妹8 小时前
深度优先算法学习
学习·算法·深度优先
GalaxyPokemon9 小时前
LeetCode - 53. 最大子数组和
算法·leetcode·职场和发展
hn小菜鸡9 小时前
LeetCode 1356.根据数字二进制下1的数目排序
数据结构·算法·leetcode
zhuiQiuMX9 小时前
分享今天做的力扣SQL题
sql·算法·leetcode