リンク:
タイトルの意味:
n ノードの無向ツリー、パス番号 1 から n、カエルは頂点 1から開始します** (0 番目の秒は頂点 1 にあります)**
一秒ごと:
カエルは、等しい確率でノードの子ノードにジャンプします。ノードに子ノードがない場合は、そのノードに留まります。
子ノードにジャンプするか、その場に留まるだけです。つまり、タイトル内の訪問したノードにはジャンプしません。
ほどく:
nはわずか100で、データは小さく、純粋なシミュレーションなので、難しい問題のようには感じません~~(拡大)~~
実際のコード:
#include<bits/stdc++.h>
#include<iomanip>
using namespace std;
void check(vector<long double>& tree)//即使检查
{
cout<<"===checking==="<<endl;
for(auto i:tree) cout<<i<<endl;
cout<<"===checked==="<<endl;
}
double frogPosition(int n, vector<vector<int>>& edges, int t, int target)
{
vector<long double>tree(n+1,0.0L);tree[1]=1;//存储概率状态
vector<vector<int>>e (n+1,vector<int>());//更改边存储结构
vector<bool>book(n+1,false);book[1]=true;//访问记录
for(auto edge:edges)//调整层次结构
{
e[edge[0]].push_back(edge[1]);//无向
e[edge[1]].push_back(edge[0]);
//cout<<edge[0]<<" "<<edge[1]<<endl;
}
vector<int>now = {1};//i秒时的点集
for(int i=1;i<=t;i++)
{
vector<int>temp;//临时点集
for(auto point:now)
{
int lg=e[point].size();
for(auto p:e[point]) if(book[p])lg--;//叶子结点数量
for(auto p:e[point])//遍历-相邻-结点
{
if(book[p]) continue;//跳过已访问
//cout<<"update"<<p<<endl;
tree[p]=tree[point]/lg;//更新子节点概率
temp.push_back(p);//加入临时点集
book[p]=true;//添加访问记录
}
if(lg) tree[point]=0;//是否有子节点,有则不呆在原地
//没有则待在原地保留概率
}
now=temp;if(now.empty()) break;//更新 当前点集
//check(tree);
}
return (double)tree[target];
}
int main()
{
int n;cin>>n;
vector<vector<int>> edges;
for(int i=1;i<n;i++)
{
vector<int>temp;
int a,b;cin>>a>>b;
temp.push_back(a);
temp.push_back(b);
edges.push_back(temp);
}
int t,target;cin>>t>>target;
double ans=frogPosition(n,edges,t,target);
cout<<fixed<<setprecision(6)<<ans<<endl;
return 0;
}
制限:
1 <= n <= 100
edges.length == n - 1
edges[i].length == 2
1 <= ai, bi <= n
1 <= t <= 50
1 <= target <= n