【BZOJ 3470】3470: Freda’s Walk 期望
3470: Freda’s Walk
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 42 Solved: 22Description
雨后的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 4Sample Output
2.000000HINT
对于 100% 的数据,2<=n<=10000,1<=m<=100000,0<=u,v<n,1<=w<=1000。
Source
【分析】
测试考这题。。错误打法 考场上竟然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