组合数?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;
}
相关推荐
万能程序员-传康Kk1 小时前
旅游推荐数据分析可视化系统算法
算法·数据分析·旅游
PXM的算法星球1 小时前
【并发编程基石】CAS无锁算法详解:原理、实现与应用场景
算法
ll7788111 小时前
C++学习之路,从0到精通的征途:继承
开发语言·数据结构·c++·学习·算法
烨然若神人~1 小时前
算法第十七天|654. 最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树
算法
爱coding的橙子2 小时前
每日算法刷题Day2 5.10:leetcode数组1道题3种解法,用时40min
算法·leetcode
程序媛小盐2 小时前
贪心算法:最小生成树
算法·贪心算法·图论
Panesle2 小时前
分布式异步强化学习框架训练32B大模型:INTELLECT-2
人工智能·分布式·深度学习·算法·大模型
多多*3 小时前
算法竞赛相关 Java 二分模版
java·开发语言·数据结构·数据库·sql·算法·oracle
逐光沧海3 小时前
数据结构基础--蓝桥杯备考
数据结构·c++·算法·蓝桥杯
Kidddddult3 小时前
力扣刷题Day 48:盛最多水的容器(283)
算法·leetcode·力扣