题解 P4745 【[CERC2017]Gambling Guide】
hzoi_liuchang · · 题解
分析
按照期望题一般的做法,我们设
设
那么
我们会发现这个式子既包含
不好直接转移
但是我们可以确定,如果
因此,我们可以利用
因为当前的值是最小的,所以一定不会有其它的点可以影响它
我们设
则
整理可得
代码
#include<cstdio>
#include<cstring>
#include<queue>
const int maxn=6e5+5;
inline int read(){
int x=0,fh=1;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') fh=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*fh;
}
int head[maxn],tot=1;
struct asd{
int to,next;
}b[maxn];
void ad(int aa,int bb){
b[tot].to=bb;
b[tot].next=head[aa];
head[aa]=tot++;
}
struct jie{
int num;
double jl;
jie(){}
jie(int aa,double bb){
num=aa,jl=bb;
}
bool operator < (const jie &A) const{
return jl>A.jl;
}
};
int n,m,du[maxn],cnt[maxn];
double sum[maxn],f[maxn];
bool vis[maxn];
std::priority_queue<jie> q;
void dij(){
q.push(jie(n,0));
while(!q.empty()){
int now=q.top().num;
q.pop();
if(vis[now]) continue;
vis[now]=1;
for(int i=head[now];i!=-1;i=b[i].next){
int u=b[i].to;
if(vis[u]) continue;
cnt[u]++;
sum[u]+=f[now];
f[u]=(du[u]+sum[u])/cnt[u];
q.push(jie(u,f[u]));
}
}
}
int main(){
memset(head,-1,sizeof(head));
n=read(),m=read();
for(int i=1;i<=m;i++){
int aa,bb;
aa=read(),bb=read();
ad(aa,bb);
ad(bb,aa);
du[aa]++,du[bb]++;
}
dij();
printf("%.10f\n",f[1]);
return 0;
}