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;
    }
    
  • 相关阅读:
    A Simple Problem with Integers poj 3468 多树状数组解决区间修改问题。
    Fliptile 开关问题 poj 3279
    Face The Right Way 一道不错的尺取法和标记法题目。 poj 3276
    Aggressive cows 二分不仅仅是查找
    Cable master(二分题 注意精度)
    B. Pasha and String
    Intervals poj 1201 差分约束系统
    UITextField的快速基本使用代码块
    将UIImage转换成圆形图片image
    color转成image对象
  • 原文地址:https://www.cnblogs.com/hbyer/p/11086733.html
Copyright © 2011-2022 走看看