zoukankan      html  css  js  c++  java
  • 1126. 最小花费

    毒瘤题。。。卡了好久

    本题求乘积最大的路径,咋一看好像是最长路直接无脑跑\(spfa\),事实上\(spfa\)的确能跑过。

    但本题也可以用\(dijkstra\)求解,原因是边权有特殊的性质:\(0<w<1\)

    这就导致了如果\(s->...->t->...>e\)\(s\)\(e\)乘积最大的路径,那么\(s->...->t\)也是\(s\)\(t\)乘积最大的路径,即满足最优子结构性质。

    因此\(dijkstra\)算法每次取权值最大的边相乘即可。

    至于\(s->...->t\)为什么一定是最大的,而不会走其他边绕路被更新。

    • 因为\(0<w<1\),走其他边绕路必然会越乘越小,必然不会更新
    const int N=2010;
    vector<PID> g[N];
    double dist[N];
    bool vis[N];
    int n,m,s,e;
    
    void dijkstra()
    {
        priority_queue<PDI> heap;
        heap.push({0,s});
        dist[s]=1;
    
        while(heap.size())
        {
            int t=heap.top().second;
            heap.pop();
    
            if(vis[t]) continue;
            vis[t]=true;
    
            for(int i=0;i<g[t].size();i++)
            {
                int j=g[t][i].fi;
                double w=g[t][i].se;
                if(dist[j] < dist[t]*w)
                {
                    dist[j]=dist[t]*w;
                    heap.push({dist[j],j});
                }
            }
        }
    }
    
    int main()
    {
        cin>>n>>m;
    
        while(m--)
        {
            int a,b,c;
            cin>>a>>b>>c;
            g[a].pb({b,(100-c)/100.0});
            g[b].pb({a,(100-c)/100.0});
        }
    
        cin>>s>>e;
    
        dijkstra();
    
        printf("%.8f\n",100/dist[e]);
        //system("pause");
    }
    
  • 相关阅读:
    VC++ 进度条的使用
    VC++ 知识点
    VC++ 遍历目录
    VC++ 目录选择对话框
    VC中的树形控件
    C++文件输入输出流
    一些有用的Sql语句
    C语言 单引号和双引号的区别
    如何让自己成为一名黑客高手全集
    顶尖黑客的故事
  • 原文地址:https://www.cnblogs.com/fxh0707/p/13734201.html
Copyright © 2011-2022 走看看