P4316 绿豆蛙的归宿

原题链接

前情提要,如果对期望的概念不清晰,请点击这里

我犯的错误:因为每条路只走一遍,而错误地判断每条路的概率相同

题解

1.对于任何一个节点来说,设其出边有len条,其子节点的期望长度为sum[j]
则该节点的期望长度为sum[j]len,根据这个式子,做法就出来了(其实我也不会证明

code 1

#include<bits/stdc++.h>
using namespace std;
vector<pair<int,int> > G[100005];
double sum[100005]={0};
double ss(int now)
{
    if(sum[now])return sum[now];
    int len=G[now].size();
    for(int i=0;i<len;i++)
    {
        int next=G[now][i].first;
        int val=G[now][i].second;
        sum[now]+=(ss(next)+val)/len;
    }
    return sum[now];
}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int u,v,w;
        cin>>u>>v>>w;
        G[u].push_back({v,w});
    }
    printf("%.2lf\n",ss(1));
    return 0;
}

这个方法用来记忆化搜索和深度搜索,但是在数据较大时容易栈溢出,内存占用较大

code 2

#include<bits/stdc++.h>
using namespace std;
vector<pair<int,int> > G[100005];
double sum[100005]={0};
int out[100005]={0};
int out2[100005]={0};
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int u,v,w;
        cin>>u>>v>>w;
        G[v].push_back({u,w});
        out[u]++;
        out2[u]++;
    }
    queue<int> q;//广度优先搜索,一定程度上减少了递归造成的栈深度大和记忆化搜索访问造成的时间资源的浪费
    q.push(n);
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        for(int i=0;i<G[now].size();i++)
        {
            int head=G[now][i].first;
            int val=G[now][i].second;
            sum[head]+=(sum[now]+val)/out[head];
            if(!--out2[head])q.push(head);//out2代表这个节点还有几个子节点没上线,等到全部上线后就能算这个节点了
        }
    }
    printf("%.2lf\n",sum[1]);
    return 0;
}

posted @   纯粹的  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示