• FJNUOJ the greed of Yehan(最长路 + 权值乘积转化)题解


    Description

     

    During the trip, Yehan and Linlin pass a cave, and there is a board at the door, which says if you have enough ambition, you will get lots of money from me. At the beginning of the cave, you will get one dollar, and then, if you go from A to B (A and B are two vertexs of an edge, and C is the length of the edge), your money will be C times larger, for example, if you have x dollars, your dollars will be C*x dollars. And the next second, a directed map appears on the entrance of the cave. After that, Yehan thinks it is a good chance to make a big money, therefore, Yehan wants to calculate how much money she can get at most. Could you help Yehan calculate how much money she can get at most? Because of the result is so large, you should mod 1000000007.You should walk from 1 to n.

    Input

     

    The first line of input is 2 integers n, m (the number of vertex, the number of edges)The following m lines,(1<=n<=1e4,1<=m<=1e5)the i-th line contains 3 integers u, v, w (1<=w<=1e9)(two vertexs and the length of the edge), we guarantee that there is no cycle.

    Output

     

    The maximum of dollars Yehan can get after mod 1000000007

    Sample Input 1 

    3 3
    1 2 100000
    2 3 10001
    1 3 100000
    3 3
    1 2 1
    2 3 1
    1 3 2
    

    Sample Output 1

    99993
    2

    我觉得这个OJ可能又要没了

    题意:从1走到n,其中有m条单向路径,走过某条路,当前拥有的价值乘上路径权值,初始价值1,问你走到n时你最多有多少价值。

    思路:最长路可以spfa取负值来做,问题在于怎么把乘法转化为加法,这里用取对数log来解决,这样就能用加法算出乘的最多的是多少了。然后我们再用一个东西保存没log前的数据来计算答案。一开始用了回溯来计算最终乘积,debug不出来了...改了直接在算最长路时就计算乘积的结果。70+%的AC率被我拖到了50%emmm

    代码:

    #include<cstdio>
    #include<set>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    const int maxn = 10000+5;
    const double INF = 0x3f3f3f3f;
    const ll MOD = 1000000007;
    struct Edge{
        int v;
        int w;
        double logw;
        Edge(int _v = 0, int _w = 0, double _logw = 0): v(_v), w(_w), logw(_logw){}
    };
    vector<Edge> G[maxn];
    bool vis[maxn];
    double dis[maxn];
    ll dist[maxn];
    void spfa(int start,int n){
        memset(vis,false,sizeof(vis));
        for(int i = 1;i <= n;i++) dis[i] = INF;
        vis[start] = true;
        dis[start] = 0;
        dist[start] = 1;
        queue<int> q;
        while(!q.empty()) q.pop();
        q.push(start);
        while(!q.empty()){
            int u = q.front();
            q.pop();
            vis[u] = false;
            for(int i = 0;i < G[u].size();i++){
                int v = G[u][i].v;
                double w = G[u][i].logw;
                if(dis[v] > dis[u] + w){    //u -> v
                    dis[v] = dis[u] + w;
                    dist[v] = (dist[u] * G[u][i].w) % MOD;
                    if(!vis[v]){
                        q.push(v);
                        vis[v] = true;
                    }
                }
            }
        }
    }
    void addEdge(int u,int v,int w){
        double logw = -log(w);
        G[u].push_back(Edge(v, w, logw));
    }
    int main(){
        int n, m;
        while(scanf("%d%d", &n, &m) != EOF){
            for(int i = 1;i <= n;i++) G[i].clear();
            int s,e;
            int t;
            while(m--){
                scanf("%d%d%d", &s, &e, &t);
                addEdge(s,e,t);
            }
            spfa(1, n);
            printf("%lld
    ", dist[n]);
        }
        return 0;
    }
    /*
    3 3
    1 2 100000
    2 3 10001
    1 3 100000
    3 3
    1 2 1
    2 3 1
    1 3 2
    */
  • 相关阅读:
    nefu17
    杭电1051
    杭电1050
    有关异或符号'^'在c++编程中的应用的讲解!!!
    杭电2095
    杭电2094
    关于set容器的简单讲解!!!
    拍拍开发
    收藏框架
    js form.submit() 无效
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9576406.html
Copyright © 2020-2023  润新知