• 校内模拟赛 虫洞(by NiroBC)


    题意:

      n个点m条边的有向图,每一天每条边存在的概率都是p,在最优策略下,询问从1到n的期望天数。

    分析:

      dijkstra。

      每次一定会优先选dp最小的后继走,如果这条边不存在,选次小的,以此类推。

      dp[i]表示从i开始到n的期望天数,从后往前推,每次取出dp最小的,更新其他点。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cctype>
    #include<cmath>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #define pa pair<double,int>
    #define fore(i, u, v) for (int i = head[u], v = e[i].to; i; i = e[i].nxt, v = e[i].to) 
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 200005;
    struct Edge { int to, nxt; double w; } e[N << 1];
    int head[N], En, n, m;
    double P[N], dp[N], sp[N], s[N], tp[N];
    bool vis[N];
    
    inline void add_edge(int u,int v,int w) {
        ++En; e[En].to = v, e[En].w = 1.0 * w / 100.0, e[En].nxt = head[u]; head[u] = En;
    }
    void Dijkstra() {
        priority_queue< pa, vector< pa >, greater< pa > > q;
        for (int i = 1; i <= n; ++i) dp[i] = 1e18, tp[i] = 1.0;
        q.push(pa(0, n)); dp[n] = 0; 
        while (!q.empty()) {
            int u = q.top().second; q.pop();
            if (vis[u]) continue; vis[u] = 1;
            fore(i, u, v) {
                double sum = s[v] + dp[u] * e[i].w * tp[v];
                double sump = sp[v] + e[i].w * tp[v];
                if (dp[v] > (sum + 1.0) / sump) {
                    dp[v] = (sum + 1.0) / sump;
                    s[v] += dp[u] * e[i].w * tp[v];
                    sp[v] += e[i].w * tp[v];
                    tp[v] *= (1 - e[i].w);
                    q.push(pa(dp[v], v));
                }
            }
        }
        printf("%.3lf
    ", dp[1]);
    }
    int main() {
        n = read(), m = read();
        for (int u, v, w, i = 1; i <= m; ++i) 
            u = read(), v = read(), w = read(), add_edge(v, u, w);
        Dijkstra();
        return 0;
    }
  • 相关阅读:
    测开之路九十五:css进阶之光标和溢出内容处理
    测开之路九十四:css之盒子模型
    测开之路九十三:css之文字样式和段落对齐
    测开之路九十二:css之背景色和背景
    测开之路九十一:css常用的选择器
    测开之路九十:css的引用方式
    测开之路八十九:HTML之图片处理
    测开之路八十八:HTML之文本格式化
    测开之路八十七:HTML之a标签的用法
    十、Django之Admin
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10645085.html
Copyright © 2020-2023  润新知