专栏文章

题解:P9428 [蓝桥杯 2023 国 B] 逃跑

P9428题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miprd7x3
此快照首次捕获于
2025/12/03 16:41
3 个月前
此快照最后确认于
2025/12/03 16:41
3 个月前
查看原文

P9428 [蓝桥杯 2023 国 B] 逃跑题解

坑点:

  1. 跳跃是向跳板星球的。
  2. 前往根结点路径上的除当前星球以外的第一个跳板星球。
  3. 求的是其花费的最短时间的期望。

思路

考虑递推,设当前节点为 uu,它的子节点为 vv
易发现当 uu 为跳板星球时,dpv=dpu+1dp_{v}=dp_{u}+1。因为我们是求的其花费的最短时间的期望。
又因 0<p<10<p<1 所以不跳是更优的。
uu 不为跳板星球时,计 cntcnt 为当前节点前往根结点路径上的跳板星球的个数。
dpv=dpu+pcnt×1dp_{v}=dp_{u}+p^{cnt}×1
又因求其花费的最短时间的期望,所以要跳就一直跳,要么不跳,走到父节点。

Code

CPP
#include<bits/stdc++.h>
#define double long double
using namespace std;
const int N=1e6+6;
vector<int> g[N];
bool is[N];
int n,m,cnt;
double dp[N];
double p;
void dfs(int x,int fa,int cnt){
	if(is[x]) cnt++;
	for(int y:g[x]){
		if(y==fa) continue;
		if(is[x]) dp[y]=dp[x]+1;
		else dp[y]=dp[x]+pow(p,cnt);
		dfs(y,x,cnt);
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0); 
	cin>>n>>m>>p;
	for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	for(int i=1;i<=m;i++){
		int x;
		cin>>x;
		is[x]=1;
	}
	dfs(1,0,0);
	double sum=0;
	for(int i=1;i<=n;i++) sum+=dp[i];
	double ans=sum/n;
	printf("%.2Lf",ans);
} 

评论

0 条评论,欢迎与作者交流。

正在加载评论...