某景区一共有
vector<pair<int, int>> e[maxn];
ll fa[maxn], dep[maxn], son[maxn], siz[maxn], top[maxn];
ll c[maxn], suf[maxn];
ll sum[maxn];
void dfs1(ll u, ll f, ll val) {
fa[u] = f;
dep[u] = dep[f] + 1;
siz[u] = 1;
sum[u] = val;
for (auto x: e[u]) {
ll v = x.first;
if (v == f) continue;
dfs1(v, u, val + x.second);
siz[u] += siz[v];
if (siz[v] > siz[son[u]]) son[u] = v;
void dfs2(ll u, ll t) {
top[u] = t;
if (!son[u]) return;
dfs2(son[u], t);
for (auto x: e[u]) {
ll v = x.first;
if (v != son[u] && v != fa[u]) dfs2(v, v);
ll lca(ll x, ll y) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
x = fa[top[x]];
return dep[x] > dep[y] ? y : x;
ll get(ll x, ll y) {
if (x == 0 || y == 0) return 0;
return sum[x] + sum[y] - 2 * sum[lca(x, y)];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, k;
cin >> n >> k;
for (int i = 1; i < n; i++) {
int u, v, z;
cin >> u >> v >> z;
e[u].emplace_back(v, z);
e[v].emplace_back(u, z);
dfs1(1, 1, 0);
dfs2(1, 1);
for (int i = 1; i <= k; i++) cin >> c[i];
for (int i = k; i >= 1; i--) suf[i] = suf[i + 1] + get(c[i], c[i + 1]);
ll pre = 0;
for (int i = 1; i <= k; i++) {
cout << pre + get(c[i - 1], c[i + 1]) + suf[i + 1] << " ";
pre += get(c[i - 1], c[i]);
return 0;
给定一棵由
vector<int> e[maxn];
ll fa[maxn], dep[maxn], son[maxn], siz[maxn], top[maxn];
ll diff[maxn];
void dfs1(ll u, ll f) {
fa[u] = f;
dep[u] = dep[f] + 1;
siz[u] = 1;
for (auto x: e[u]) {
ll v = x;
if (v == f) continue;
dfs1(v, u);
siz[u] += siz[v];
if (siz[v] > siz[son[u]]) son[u] = v;
void dfs2(ll u, ll t) {
top[u] = t;
if (!son[u]) return;
dfs2(son[u], t);
for (auto x: e[u]) {
ll v = x;
if (v != son[u] && v != fa[u]) dfs2(v, v);
ll lca(ll x, ll y) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
x = fa[top[x]];
return dep[x] > dep[y] ? y : x;
void dfs(int x, int fx) {
for (auto y: e[x]) {
if (y == fx) continue;
dfs(y, x);
diff[x] += diff[y];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, m;
cin >> n >> m;
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
e[u].emplace_back(v);
e[v].emplace_back(u);
dfs1(1, 1);
dfs2(1, 1);
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
diff[u]++, diff[v]++, diff[lca(u, v)] -= 2;
dfs(1, 0);
ll ans = -1;
for (int i = 0; i <= n; i++) if (diff[i] >= m) ans = i - 1;
cout << ans << endl;
return 0;
第15届蓝桥杯省赛已于2024年8月24日正式落下帷幕,比赛仍然采取线上形式。本次省赛初级组和中级组分开考试,上午是初级组,下午是中级组。这是Scratch初级组真题,试题包括两种题型,分别是选择题和编程创作题,其中选择题5道,都是和Scratch编程知识相关的题目,编程部分也是5道题,分别是猪八戒落地、游乐场、画西瓜、找不同和消除数字球。
这个炉子有一个称作转换率的属性V,V 是一个正整数,这意味着消耗V 个普通金属O 恰好可以冶炼出一个特殊金属X,当普通金属O 的数目不足V 时,无法继续冶炼。所以在地图周围一圈, 我们增加一圈0作为外海, dfs遍历外海每一个方格, 若与外海方格相邻的岛屿未被遍历过,那么这就是一个新的岛屿, 再用一个dfs去遍历这个岛。地图外的方格我们全部视为海, 与地图外的海连通的海都视为外海, 可以发现, 接触到了外海的岛屿, 就一定不是其它岛屿的子岛。对于每一条记录, 都可以求出转换率V的一个取值范围。
参加了两届蓝桥杯以及做过了往年的真题我的直观感受是蓝桥杯不再那么“暴力”了,而是逐渐趋向DP和搜素图论方面了。下面是第十四届蓝桥杯省赛C/C++ B组真题及题解,希望对阅读的你有所帮助。
先用边缘的海水进行bfs求出"真的海水",然后再对所有岛屿进行BFS,此时BFS的时候非真的海水可以直接识别为陆地然后入队。每次用第i个数组开头的字母对应的数组更新f[i],然后再用f[i]反过来更新bac即可。因此我们可以开一个数组f[i]表示前i个数字,以第i个结尾的最大接龙子序列。删最少数使得他是接龙序列,即求原序列的最大接龙子序列,然后用n减去。然后枚举开头的位置,二分出结尾在另一个数组的合法位置,直接累加答案。因此直接二分即可,顺便输出一下结果对应的函数值。set维护每个位置的值和要删的最小值。
思路:一开始我想错了,把子岛也求了。第一遍把岛屿外面的0全改成2(8方搜索),然后把里面的0改成1,第二for循环搜索遍历岛屿(四方搜索),看看有几个。假设一下,岛屿外是海,岛屿内是河。图中是有两个岛的,图1的3点是海,2点也是,2点8方可以搜到3,他们也算是联通的;思路:找到所有头l和尾r出现的位置,然后存起来。利用r[j] >= l[i] + k - 1这一关系,找出每一个头的总数,加和即可。思路:这题我写了几个数,发现就是取一堆数据的最小值的最大值,和最大值的最小值(人话:公共部分)。
第一次打蓝桥,寄了,300元买了两个脆脆鲨和一瓶水哈哈可以在下面民间网站提交测试教训 :(1)直接输出骗样例的别忘了先把题目的输入写上(2)读清楚题目要求 (3)一定要return 0;啊啊啊啊(4)devc++的输入窗口可以从属性哪里改成可复制(傻傻的自己敲案例)(5)把思路想好了再动手,(别白白浪费时间)