IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Acwing 217. 绿豆蛙的归宿 -> 正文阅读

[数据结构与算法]Acwing 217. 绿豆蛙的归宿

Acwing 217. 绿豆蛙的归宿

题意:

给出一个有向无环的连通图,起点为 1,终点为 N,每条边都有一个长度。

数据保证从起点出发能够到达图中所有的点,图中所有的点也都能够到达终点。

绿豆蛙从起点出发,走向终点。

到达每一个顶点时,如果有 K 条离开该点的道路,绿豆蛙可以选择任意一条道路离开该点,并且走向每条路的概率为 1/K。

现在绿豆蛙想知道,从起点走到终点所经过的路径总长度的期望是多少?

题解:

这个文章讲的不错
设dp[x]表示状态为x到终点n的期望路径总长,显然dp[n] = 0,所以要从dp[n]倒着推dp[1]
我们设一条有向边,x->y,那么就有:
dp[x] = P * ∑dp[y] + w[x->y]
P = (1/degree(x)),degree(x)为x的出度,有多少出度说明有多少种选择,概率就是倒数
w表示转移对答案的贡献
dp可以通过记忆化搜索求,也就通过拓扑排序求

代码:

记忆化搜索

#include<bits/stdc++.h>
#define debug(a,b) printf("%s = %d\n",a,b);
typedef long long ll;
using namespace std;

inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
const int maxn=3e5+9;
vector<pair<int,int> >vec[maxn]; 
double dp[maxn];
int n,m;
double dfs(int u){
	if(u==n)return 0;
	if(dp[u])return dp[u];
	for(int i=0;i<vec[u].size();i++){
		int v=vec[u][i].first;
		int w=vec[u][i].second;
		dp[u]+=dfs(v)+w;
	}
	dp[u]=dp[u]/int(vec[u].size());
	return dp[u];
}
int main()
{
	
	cin>>n>>m;
	
	for(int i=1;i<=m;i++){
		int u,v,w;
		cin>>u>>v>>w;
		vec[u].push_back({v,w});
	}
	
	printf("%.2f",dfs(1));
}

拓扑排序

时间复杂度O(n+m)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
typedef long long ll;
const int inf=1e9+7;
inline int read()//读优
{
    int p=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){p=p*10+c-'0';c=getchar();}
    return f*p;}
const int maxn=100003;
const int maxm=200003;
struct Edge
{
    int from,to,w;
}p[maxm];
int n,m,cnt,head[maxm],in[maxn],dg[maxn];
double f[maxn];//f[x]表示x点到终点n的期望路径总长 
inline void add_edge(int x,int y,int W)//加边
{
    cnt++;
    p[cnt].from=head[x];
    head[x]=cnt;
    p[cnt].to=y;
    p[cnt].w=W;
}
inline void toposort()//拓扑排序
{
    queue <int> q;
    q.push(n);
    while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=head[x];i;i=p[i].from)
                {
                    int y=p[i].to;
                    f[y]+=(f[x]+p[i].w)/dg[y];//dp转移 
                    if(!(--in[y]))q.push(y);
                }
        }
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=m;i++)
        {
            int x=read(),y=read(),w=read();
            add_edge(y,x,w);//反向建图 
            in[x]++,dg[x]++;
        }
    toposort();
    printf("%.2lf\n",f[1]);
    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-16 11:33:17  更:2021-07-16 11:35:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 9:51:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计