2023ICPC网络赛第二场
I Impatient Patient
题意:
从0到n,有两种操作
1.什么都不做,花费一天,从i到i+1
2.尝试做事,花费一天,成功概率pi,成功后直接到 n ,失败回到a[i]
思路:如果存在一个可以挑战成功的最优状态,我们挑战失败后也会恢复到这一个点继续挑战,直至挑战成功,那么我们枚举哪个状态最优即可,那么我们就是先第一个操作走到i点,然后当前的期望就是i为基础,然后一直挑战,第一次挑战是p * 1 ,失败会多i-a[i]+1天(当前操作用一天,回到i点用i-a[i]天),记作d,
E(i)=i+\sum_{k=0}^{+\infty}(1+kd)*p[i]*(1-p[i])^k
E(i)=i+p[i]*d*\sum_{k=0}^{+\infty}k*(1-p[i])^k+p[i]*\sum_{k=0}^{+\infty}(1-p[i])^k
令q=1-p;
E(i)=i+p[i]*d*\sum_{k=0}^{+\infty}k*q[i]^k+p[i]*\sum_{k=0}^{+\infty}q[i]^k
:\sum_{k=0}^{+\infty}k*q[i]^k =q[i]/(1-q[i])^2
: \sum_{k=0}^{+\infty}q[i]^k =1
E(i)=i+p[i]*d*q[i]/(1-q[i])^2+1
diamond:
#include<bits/stdc++.h>
using namespace std;
#define double long double
void solve(){
int n;
cin>>n;
vector< double >a(n),q(n),p(n);
for (int i = 0; i <n ; ++i) {
cin>>a[i];
}
for (int i = 0; i <n ; ++i) {
cin>>p[i];
p[i]/=100000;
q[i]=1-p[i];
}
double ans=n;
for (int i = 0; i <n ; ++i) {
if(p[i]==0)continue;
double res=i+(p[i]*(i-a[i]+1)*q[i])/((1-q[i])*(1-q[i]))+1;
ans=min(res,ans);
}
::printf("%.13Lf\n",ans);
}
signed main() {
int t;
cin>>t;
while (t--){
solve();
}
}
E.Another Bus Route Problem
题意:有大小为n的一棵树,树上有m条路,路只能从起点或者终点进入,但可以在任意一处出去,求到1到 结点2-n 最少需要走几条路?
思路:我们考虑到要想从1到其他节点,那么我们首先要到达1,才能到达其他节点,所以我们现要求每一个可上车和下车的车站到达1的最短路径,然后我们就是要确定每个可到达的可上下车的车站的最短路径,这个是怎么确定的呢,其实我们可以这样想,从1到x若是可以到达,那么1到x的路径上的所有点,都可以先到x然后到1,我们是这样进行更新的,我们对第二张图进行BFS的遍历,BFS就是最短的,先遍历到的节点,往上搜索,搜索到没被更新的点就更新,搜到了被更新到的点那么就break,这样就可以保证最短的答案被记录到了可到达的点,若没被更新过的点,那么表示无法到达
diamond:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int fa[N];
vector<int>g[N];
int ans[N];
const int INF=INT_MAX;
void solve(){
int n,m;
cin>>n>>m;
fill(ans+1,ans+n+1,INF);
for (int i = 2; i <=n ; ++i) {
cin>>fa[i];
}
for (int i = 0; i <m ; ++i) {
int x,y;
cin>>x>>y;
g[x].push_back(y);
g[y].push_back(x);
}
queue<int>q;
q.push(1);
ans[1]=0;
while (!q.empty()){
auto t=q.front();
q.pop();
for (auto i:g[t]) {
int f=i;
while (ans[f]==INF){
ans[f]=ans[t]+1;
if(g[f].size()){
q.push(f);
}
f=fa[f];
}
}
}
for (int i = 2; i <=n ; ++i) {
if(ans[i]!=INF)
cout<<ans[i]<<' ';
else cout<<"-1 ";
}
}
signed main() {
int t=1;
// cin>>t;
while (t--){
solve();
}
}