• HDU4318 Power transmission 模型转化


    这题在比赛的时候没做出来实在是不应该。本来也是用对数处理的,但是后面写的七零八落的。

    这题也可以直接求,记录每个点最少消耗的流量,剩余流量为初始流量减去这个值,逐步向下迭代。

    当然这里可以去求他的剩余值,根据公式 最后的流量 L = I * (1-p1) * (1-p2) * ... * (1-pn) 我们对两边同时取对数的话,那么我们就将乘法化成了加法,并且直接求一个最长路就可以了。最后再拿总流量减去最大的剩余量即可。

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #define eps 1e-6
    using namespace std;
    
    int head[50005], N, idx, S, T, P, q[10000005], visit[50005];
    double dis[50005];
    
    struct Edge
    {
        int v, next;
        double fee;
    }e[2500005];
    
    void insert(int x, int y, int fee)
    {
        ++idx;
        e[idx].v = y, e[idx].fee = log(1 - fee/100.);
        e[idx].next = head[x], head[x] = idx;
    }
    
    void spfa()
    {
        int front = 0, tail = 1, pos;
        q[tail] = S;
        fill(dis+1, dis+N+1, 0);
        dis[S] = log(1.*P);
        while (front != tail) {
            pos = q[++front];
            visit[pos] = 0;
            for (int u = head[pos]; u != -1; u = e[u].next) {
                if (dis[pos] + e[u].fee - dis[e[u].v] > eps) {
                    dis[e[u].v] = dis[pos] + e[u].fee;
                    if (!visit[e[u].v]) {  // spfa中防止多次入队
                        q[++tail] = e[u].v;
                        visit[e[u].v] = 1;
                    }
                }
            }
        }
        if (dis[T] == 0) {
            puts("IMPOSSIBLE!");
        }
        else {
            printf("%.2lf\n", P - exp(dis[T]));
        }
    }
    
    int main()
    {  
        int M, y, fee;
        while (scanf("%d", &N) == 1) {
            memset(head, -1, sizeof (head));
            memset(visit, 0, sizeof (visit));
            idx = -1;
            for (int i = 1; i <= N; ++i) {
                scanf("%d", &M);
                for (int j = 1; j <= M; ++j) {
                    scanf("%d %d", &y, &fee);
                    insert(i, y, fee);
                }
            }
            scanf("%d %d %d", &S, &T, &P);
            spfa();
        }
        return 0;
    }
  • 相关阅读:
    csu 1604 SunnyPig (bfs)
    openjudge 大师兄,师傅被妖怪抓走啦
    poj 3264 线段树 求区间最大最小值
    bzoj 1012 维护一个单调数列
    poj 1840 暴力+标记
    最短路径(Dijkstra实现)
    最小生成树(Kruskal实现)
    最小生成树(Prim实现)
    拓扑排序(Kahn实现)
    拓扑排序(DFS实现)
  • 原文地址:https://www.cnblogs.com/Lyush/p/2611050.html
Copyright © 2020-2023  润新知