【BZOJ 3470】3470: Freda’s Walk 期望

3470: Freda’s Walk

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 42  Solved: 22

Description

雨后的Poetic Island空气格外清新,于是Freda和Rainbow出来散步。 Poetic Island的交通可以看作一张n个点、m 边的有向无环图。由于刚下过雨,每条边都有一个积水深度,而恰好Freda 和Rainbow都喜欢踩水玩儿,于是Ta们从某个点出发,选择走向哪条边的概率与该边的积水深度是成正比的。即:如果Freda和Rainbow现在在点u,点u 出发的所有边的积水深度之和为s,从u到v的边积水深度为w,那么Ta们选择走向v的概率就是 w/s。  
Ta们会一直走下去,直到到达一个没有出边的点,那么散步的路程长度就是走过的边的数量。更特殊的是,Freda和Rainbow在出发之前还可以选择一条边,在散步过程中无视这条边的存在(当然也可以不选择)。请你帮忙计算一下,Ta 们从0号点出发,散步的路程长度的期望值最大是多少?

Input

第一行两个正整数 n、m。 
接下来m行每行三个整数u、v、w,表示从u到v有一条无向边,积水深度为w。

Output

输出Freda和Rainbow散步的路程长度的最大期望值,四舍五入保留六位小数。

Sample Input

4 5

0 1 2

0 2 1

0 3 3

1 3 1

2 3 4

Sample Output

2.000000

HINT

对于  100% 的数据,2<=n<=10000,1<=m<=100000,0<=u,v<n,1<=w<=1000。

Source

Adera 2 杯省选模拟赛

【分析】

  测试考这题。。错误打法 考场上竟然AC了【黑人问号脸??

  也算给自己提个醒吧,DAG和树终究是不一样的。不能f[i][0]和f[i][1]表示后面割还是没割,比如:

  

  割3后面那条边是f[2][1]和f[3][1],但是不会让他们转移到f[1][1],因为你规定只有一个儿子可以选割,但是是可以的,因为只是个割了3下面那条边。。

  所以这个方法不行。

  考虑割一条边对答案的影响。

  假设割x->y,只会影响f[x]以及1到x路径上的点。

  但是我们只需要知道x的f值的改变对1这个点的f值的影响。

  假设从1走到x的概率是p,假设那么f[1]会增加(f[x]‘-f[x])*p,直接枚举割哪条边然后计算出这个求max就好了。

  【ORZORZORZ...

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<cmath>
 7 using namespace std;
 8 #define Maxn 100010
 9 #define Maxm 1000010
10
11 struct node
12 {
13     int x,y,c,next,p;
14 }t[Maxm],tt[Maxm];
15 int first[Maxn],len;
16 int d[Maxn];
17
18 int ft[Maxn];
19 void ins(int x,int y,int c)
20 {
21     t[++len].x=x;t[len].y=y;t[len].c=c;
22     t[len].next=first[x];first[x]=len;t[len].p=1;
23     tt[len].x=y;tt[len].y=x;tt[len].c=c;tt[len].next=ft[y];ft[y]=len;
24 }
25
26 bool vis[Maxn];
27 double g[Maxn];
28 void dfs2(int x)
29 {
30     if(vis[x]) return;vis[x]=1;
31     if(x==1) {g[x]=1;return;}
32     for(int i=ft[x];i;i=tt[i].next)
33     {
34         int y=tt[i].y;
35         dfs2(y);
36         g[x]+=g[y]*tt[i].c*1.0/d[y];
37     }
38 }
39
40 double f[Maxn];
41 void dfs(int x)
42 {
43     if(vis[x]) return;vis[x]=1;
44     f[x]=0;
45     for(int i=first[x];i;i=t[i].next) if(t[i].p)
46     {
47         int y=t[i].y;
48         dfs(y);
49         f[x]+=(f[y]+1)*t[i].c*1.0/d[x];
50     }
51     return;
52 }
53
54 int main()
55 {
56     int n,m;
57     scanf("%d%d",&n,&m);
58     len=0;
59     memset(first,0,sizeof(first));
60     memset(ft,0,sizeof(ft));
61     for(int i=1;i<=m;i++)
62     {
63         int x,y,c;
64         scanf("%d%d%d",&x,&y,&c);
65         x++;y++;
66         d[x]+=c;
67         ins(x,y,c);
68     }
69     memset(vis,0,sizeof(vis));
70     for(int i=1;i<=n;i++) g[i]=0;
71     for(int i=1;i<=n;i++) dfs2(i);
72     memset(vis,0,sizeof(vis));
73     dfs(1);
74     double mx=f[1];
75     for(int i=1;i<=len;i++)
76     {
77         int x=t[i].x,y=t[i].y;
78         double ad;
79         if(d[x]!=t[i].c) ad=(f[x]*d[x]*1.0/(d[x]-t[i].c)-(f[y]+1)*t[i].c*1.0/(d[x]-t[i].c))-f[x];
80         else ad=-f[x];
81         mx=max(mx,f[1]+g[x]*ad);
82     }
83     printf("%.6lf\n",mx);
84     return 0;
85 }

2017-04-24 18:51:22

时间: 2024-10-06 02:44:53

【BZOJ 3470】3470: Freda’s Walk 期望的相关文章

[BZOJ 1076][SCOI2008]奖励关(期望+状压Dp)

Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物, 每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃).  宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相互独立.也就是说,即使前k-1次系统都抛出宝物1( 这种情况是有可能出现的,尽管概率非常小),第k次抛出各个宝物的概率依然均为1/n. 获取第i种宝物将得到Pi 分,但并不是每种宝物都是可以随意获取的.第i种宝物有一个前

[BZOJ 4008][HNOI2015]亚瑟王(期望Dp)

Description 小 K 不慎被 LL 邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑. 他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂 亮.众所周知,亚瑟王是一个看脸的游戏,技能的发动都是看概率的.作为一个非 洲人,同时作为一个前 OIer,小 K 自然是希望最大化造成伤害的期望值.但他已 经多年没写过代码,连 Spaly都敲不对了,因此,希望你能帮帮小 K,让他感受一 下当欧洲人是怎样的体验. 本题中我们将考虑游戏的一个简化版模型. 玩家有一套卡牌,共

BZOJ 1076 奖励关(状压期望DP)

当前得分期望=(上一轮得分期望+这一轮得分)/m dp[i,j]:第i轮拿的物品方案为j的最优得分期望 如果我们正着去做,会出现从不合法状态(比如前i个根本无法达到j这种方案),所以从后向前推 如果当前方案j里具备了取k这个物品的条件 那么dp[i,j]+=max{dp[i+1,j],dp[i+1,j  or  1<<(k?1)]+x[k]} 否则dp[i,j]+=dp[i+1,j] #include<cstdio> #include<iostream> using n

BZOJ 3091: 城市旅行 [LCT splay 期望]

3091: 城市旅行 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1454  Solved: 483[Submit][Status][Discuss] Description Input Output Sample Input 4 5 1 3 2 5 1 2 1 3 2 4 4 2 4 1 2 4 2 3 4 3 1 4 1 4 1 4 Sample Output 16/3 6/1 HINT 对于所有数据满足 1<=N<=50,000 1&l

bzoj 1076 状态压缩最优期望

题意: 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随 机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃). 宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相互独立.也就是说,即使前k-1次系统都抛出宝物1(这种情况是有可能出现的,尽管概率非常 小),第k次抛出各个宝物的概率依然均为1/n. 获取第i种宝物将得到Pi分,但并不是每种宝物都是可以随意获取的.第i种宝物有一个前提宝物集合Si.只有

BZOJ 2878 [Noi2012]迷失游乐园 树形期望DP+基环树

题意:链接 方法:树形期望DP+基环树 解析: 首先先看前50%的数据 是一棵树 那么我们可以搞树形DP 然后设几个正常的数组 sum[i]代表i走i的子节点的期望的和. down[i]代表从底下走到i的期望. size[i]代表i的儿子个数 up[i]代表从i往上走的期望 然后就可以推式子了 显而易见地可以推出来up的式子 然后有一些奇怪的关于根节点的特判,注意一下就OK了. 然后后50% 我们发现它是一个基环树? 那么首先可以乱搞出来环上的点,然后记录一下这个环上的点的连接方式,求一下相邻两

BZOJ 3566 SHOI2014 概率充电器 树形期望DP

题目大意:给定一棵树,每个点初始有一个概率为1,为1的节点会沿着边以边权上的概率向四周扩散,求最终期望有多少个点是1 OTZ 不想写题解了贴个代码吧= = 如果有不明白做法的直接问我就好了= = #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 500500 #define EPS 1e-7 using namespace std;

BZOJ 1426--收集邮票(概率与期望&amp;DP)

1426: 收集邮票 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 504  Solved: 417[Submit][Status][Discuss] Description 有n种不同的邮票,皮皮想收集所有种类的邮票.唯一的收集方法是到同学凡凡那里购买,每次只能买一张,并且买到的邮票究竟是n种邮票中的哪一种是等概率的,概率均为1/n.但是由于凡凡也很喜欢邮票,所以皮皮购买第k张邮票需要支付k元钱. 现在皮皮手中没有邮票,皮皮想知道自己得到所有种类

【BZOJ】3143: [Hnoi2013]游走 期望+高斯消元

[题意]给定n个点m条边的无向连通图,每条路径的代价是其编号大小,每个点等概率往周围走,要求给所有边编号,使得从1到n的期望总分最小(求该总分).n<=500. [算法]期望+高斯消元 [题解]显然,应使经过次数越多的边编号越小,问题转化为求每条边的期望经过次数. 边数太多,容易知道f(u,v)=f(u)/out(u)+f(v)/out(v),所以转化为求每个点的期望经过次数,这就是驱逐猪猡了. 设f[x]表示点x的期望经过次数,根据全期望公式(讨论"经过"的问题不能依赖于下一步