Description
一个无向连通图,顶点从1编号到N,边从1编号到M。
小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和。
现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。
Input
第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v≤N),表示顶点u与顶点v之间存在一条边。 输入保证30%的数据满足N≤10,100%的数据满足2≤N≤500且是一个无向简单连通图。
Output
仅包含一个实数,表示最小的期望值,保留3位小数。
Sample Input
3 3
2 3
1 2
1 3
Sample Output
3.333
HINT
边(1,2)编号为1,边(1,3)编号2,边(2,3)编号为3。
经某位大神的讲解,瞬间领悟了,原来这么简单
设点i的期望经过次数为f[i],那么就有f[i]=∑f[j]/d[j](j与i之间有边相连,d[j]为点j关联的边数)
因为一开始在点1上,所以f[1]还要加上一个1
又因为到了n点就结束,所以点n不能为其他点提供期望经过次数,设f[n]=0
所以我们可以列出n-1个方程,一共有n-1个变量,可以解出n-1个点的期望经过次数
然后我们可以求出每条边的期望经过次数
对于每一条边(v,u)它的期望经过次数为f[v]/d[i]+f[u]/d[v]
再排个序,根据排序不等式我们知道,倒序才是最小的,倒着标号,然后求和得到最小期望总分
最开始在BZOJ上过了,Wikioi上没过
我以为是精度太高了,把extended改成了double,还是没过
后来下了标程才知道,原来在判断是否为0时用到了精度判断
在BZOJ上不能用精度判断,在wikioi上必须用精度判断
注意细节啊
1 const 2 eps=1e-7; 3 var 4 n,m:longint; 5 d:array[0..510]of longint; 6 f:array[0..510,0..510]of extended; 7 v,u:array[0..250000]of longint; 8 exp:array[0..250000]of extended; 9 ans:extended; 10 11 procedure swap(var x,y:extended); 12 var 13 t:extended; 14 begin 15 t:=x; 16 x:=y; 17 y:=t; 18 end; 19 20 procedure sort(l,r:longint); 21 var 22 i,j:longint; 23 z:extended; 24 begin 25 i:=l; 26 j:=r; 27 z:=exp[(l+r)>>1]; 28 repeat 29 while exp[i]>z do 30 inc(i); 31 while exp[j]<z do 32 dec(j); 33 if i<=j then 34 begin 35 swap(exp[i],exp[j]); 36 inc(i); 37 dec(j); 38 end; 39 until i>j; 40 if j>l then sort(l,j); 41 if i<r then sort(i,r); 42 end; 43 44 procedure main; 45 var 46 i,j,k:longint; 47 s:extended; 48 begin 49 read(n,m); 50 for i:=1 to m do 51 begin 52 read(v[i],u[i]); 53 inc(d[v[i]]); 54 inc(d[u[i]]); 55 end; 56 for i:=1 to n-1 do 57 f[i,i]:=-1; 58 for i:=1 to m do 59 begin 60 f[v[i],u[i]]:=f[v[i],u[i]]+1/d[u[i]]; 61 f[u[i],v[i]]:=f[u[i],v[i]]+1/d[v[i]]; 62 end; 63 f[1,n]:=-1; 64 for i:=2 to n-1 do 65 f[i,n]:=0; 66 for i:=1 to n-2 do 67 begin 68 for j:=i to n-1 do 69 if f[j,i]<>0 then break; 70 for k:=i to n do 71 swap(f[i,k],f[j,k]); 72 for j:=i+1 to n-1 do 73 if abs(f[j,i])-eps>0 then 74 begin 75 s:=f[j,i]/f[i,i]; 76 f[j,i]:=0; 77 for k:=i+1 to n do 78 f[j,k]:=f[j,k]-s*f[i,k]; 79 end; 80 end; 81 for i:=n-1 downto 1 do 82 begin 83 for j:=i+1 to n-1 do 84 f[i,n]:=f[i,n]-f[j,0]*f[i,j]; 85 f[i,0]:=f[i,n]/f[i,i]; 86 end; 87 for i:=1 to m do 88 begin 89 exp[i]:=exp[i]+f[v[i],0]/d[v[i]]; 90 exp[i]:=exp[i]+f[u[i],0]/d[u[i]]; 91 end; 92 sort(1,m); 93 for i:=1 to m do 94 ans:=ans+i*exp[i]; 95 write(ans:0:3); 96 end; 97 98 begin 99 main; 100 end.