这是一道概率的题QAQ,本蒟蒻概率思想菜的一匹
题目背景 随着新版百度空间的上线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿。 题目描述 给出一个有向无环图,起点为1终点为N,每条边都有一个长度,并且从起点出发能够到达所有的点,所有的点也都能够到达终点。绿豆蛙从起点出发,走向终点。 到达每一个顶点时,如果有K条离开该点的道路,绿豆蛙可以选择任意一条道路离开该点,并且走向每条路的概率为 1/K 。 现在绿豆蛙想知道,从起点走到终点的所经过的路径总长度期望是多少? 输入输出格式 输入格式: 第一行: 两个整数 N M,代表图中有N个点、M条边 第二行到第 1+M 行: 每行3个整数 a b c,代表从a到b有一条长度为c的有向边 输出格式: 从起点到终点路径总长度的期望值,四舍五入保留两位小数。 输入输出样例 输入样例#1: 复制 4 4 1 2 1 1 3 2 2 3 3 3 4 4 输出样例#1: 复制 7.00 说明 对于20%的数据 N<=100 对于40%的数据 N<=1000 对于60%的数据 N<=10000 对于100%的数据 N<=100000,M<=2*N
这道题我周围的巨佬都是正着建边正着搞,好像只有我是倒着弄得QAQ
这个方程网上也是有的
dp[u]=∑u−>v(dp[v]+val)/out[u]
只有倒着的本蒟蒻才能理解,期望这个东西就是值*概率
倒着就变成了
dp[to]=∑u−>v(dp[now]+val)/in[to]
附一个拓扑的模板
1 while(!qq.empty()) 2 { 3 int now=qq.front();qq.pop(); 4 for(int i=head[now];i!=-1;i=edge[i].nxt) 5 { 6 int to=edge[i].to; 7 8 ... 9 10 in[to]--; 11 if(!in[to])qq.push(to); 12 } 13 }
拓扑还是比较好理解的一个东西,
还有一件事,是我左面大佬告诉我的,就是
忘记float这个东西,你的脑子里只有double,特别是概率这种题型
代码
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<queue> 5 #define N 100011 6 using namespace std; 7 struct node{int to,nxt,val;}edge[2*N]; 8 int n,m,u,v,w,cnt=1; 9 int head[N],in[N],in2[N]; 10 double dis[N]; 11 queue<int>qq; 12 inline void add(int u,int v,int w) 13 { 14 edge[cnt].to=v; 15 edge[cnt].val=w; 16 edge[cnt].nxt=head[u]; 17 head[u]=cnt++; 18 in[v]++,in2[v]++; 19 } 20 int main() 21 { 22 memset(head,-1,sizeof(head)); 23 scanf("%d%d",&n,&m); 24 for(int i=1;i<=m;i++) 25 { 26 scanf("%d%d%d",&v,&u,&w); 27 add(u,v,w); 28 } 29 for(int i=1;i<=n;i++) 30 if(!in[i])qq.push(i); 31 while(!qq.empty()) 32 { 33 int now=qq.front();qq.pop(); 34 for(int i=head[now];i!=-1;i=edge[i].nxt) 35 { 36 int to=edge[i].to; 37 dis[to]+=(dis[now]+edge[i].val)*1.0/(float)in2[to]; 38 in[to]--; 39 if(!in[to])qq.push(to); 40 } 41 } 42 printf("%.2lf",dis[1]); 43 return 0; 44 }