zoukankan      html  css  js  c++  java
  • [BZOJ5197] [CERC2017]Gambling Guide

    [BZOJ5197] [CERC2017]Gambling Guide

    题目链接

    https://www.lydsy.com/JudgeOnline/problem.php?id=5197

    Solution

    据说这种题有套路...但是窝不会...所以窝看了题解才知道做的...

    首先这种期望题一般状态是(f_x)表示(x)(n)的期望步数,由于要求最优策略,那么我们随机到一条边时从(f_x,f_v)里选一个最小的转移即可,具体的:

    [f_x=frac{1}{d_x}sum_{vin son_x}(1+min(f_x,f_v)) ]

    其中(f_n=0)

    然后我么考虑从(n)号点开始更新其他的点,仿照( m Dijkstra)的形式。

    我们假定一开始除了(n)号点以外其他的点(f_x=+infty),且每个(min)都选(f_x)

    那么设当前枚举到的点为(x),边为((x,v)),那么如果(f_vgeqslant f_x)时,(v)号点的(min)会改选为(f_x),那么我们更新一下(f_v)就好了。

    显然这样更新满足每次选到的都是最小的点,而且他不会再被更新。

    复杂度(O(nlog n))

    #include<bits/stdc++.h>
    using namespace std;
      
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
       
    void print(int x) {
        if(x<0) putchar('-'),x=-x;
        if(!x) return ;print(x/10),putchar(x%10+48);
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
      
    #define lf double
    #define ll long long 
      
    #define pii pair<int,int >
    #define vec vector<int >
      
    #define pb push_back
    #define mp make_pair
    #define fr first
    #define sc second
      
    #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) 
      
    const int maxn = 4e5+10;
    const int inf = 1e9;
    const lf eps = 1e-8;
    const int mod = 1e9+7;
      
    lf f[maxn],s[maxn];
    int d[maxn],c[maxn],head[maxn],tot,n,m,vis[maxn];
      
    struct edge{int to,nxt;}e[maxn<<1];
      
    void ins(int u,int v) {e[++tot]=(edge){v,head[u]},head[u]=tot;}
      
    priority_queue<pair<lf,int > > q;
      
    int main() {
        read(n),read(m);
        for(int i=1,x,y;i<=m;i++) read(x),read(y),ins(x,y),ins(y,x),d[x]++,d[y]++;
        memset(f,127,sizeof f);f[n]=0;
        q.push(mp(0.0,n));
        while(!q.empty()) {
            int x=q.top().second;q.pop();
            if(vis[x]) continue;vis[x]=1;
            for(int v,i=head[x];i;i=e[i].nxt)
                if(f[v=e[i].to]>=f[x])
                    c[v]++,s[v]+=f[x],f[v]=(s[v]+d[v])/(lf)c[v],q.push(mp(-f[v],v));
        }printf("%.10lf
    ",f[1]);
        return 0;
    }
    
  • 相关阅读:
    你不知道的JS系列上( 40 ) - 什么是类
    CF356E
    [HDU4135]CO Prime(容斥)
    [POJ 2888]Magic Bracelet[Polya Burnside 置换 矩阵]
    Polya定理与Burnside引理
    选举
    David与Vincent的博弈游戏[树型DP]
    Vincent的城堡
    三元组
    vue打包体积优化之旅
  • 原文地址:https://www.cnblogs.com/hbyer/p/11086733.html
Copyright © 2011-2022 走看看