zoukankan      html  css  js  c++  java
  • [无聊测试赛] T8 佳佳的魔法药水

    思路比较新奇,但是想到了题目还是挺好做的

    看到最小和次数可以想到最短路.看到数据范围可以想到必须在跑dij的时候记录次数.由于要记录的是最短路的方案,易证如果一种药有一种更便宜的配置方法,我们不会记录贵的那种.

    于是,我们可以将这道题转化为一个用堆优化的dij.如果一种药水在堆顶,那么这种药水不可能有更便宜的配置方法

    如果由A药水和B药水合成C药水比之前找到的配置方法便宜,那么C药水的配置方法数量为 A药水的配置方法 (*) B药水的配置方法.

    如果由A药水和B药水合成C药水等于之前找到的配置方法,那么C药水的配置方法数量为 C药水的配置数量 (+) A药水的配置方法 (*) B药水的配置方法.

    在遍历图的时候,只有两种药水都被证实为最小花费,他们合成的药水才会是他们能得到的最小值.要证明这两种的最小花费的方法是:如果他俩在堆里出现过,那么他们一定是最小花费.这个操作可以用vis数组实现

    遍历整张图,最后到0的距离+配置0的方案数就是答案

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <vector>
    using namespace std;
    #define pp pair<int,int>
    #define f first
    #define s second
    const int MAXN = 1e3+5;
    vector<pp> adj[MAXN];
    priority_queue<pp> q;
    int n;
    int dist[MAXN], ways[MAXN],ans1,ans2,in[MAXN];
    bool vis[MAXN];
    int main(){
      cin >> n;
      for (int i=0;i<n;i++){
        cin >> dist[i];
        ways[i] = 1;//一开始都只有一种
        q.push(make_pair(-dist[i],i));//扔进堆
      }
      ans1 = dist[0]; ans2 = 1;
      int a,b,c;
      while(cin >> a >> b >> c){
        adj[a].push_back(make_pair(b,c));
        if(a!=b)adj[b].push_back(make_pair(a,c));//注意,他可能出现A+A=C.这种情况不需要连两次边
      }
      while(!q.empty()){
        int qf = -q.top().f, qs = q.top().s; q.pop();
        if (dist[qs]!=qf) continue;//如果一个点的最小距离不等于在堆顶的距离,说明这个点已经更新过了,不需要再更新
        vis[qs] = true;//这个点被拿过了
        for (pp v : adj[qs]){
          if (!vis[v.f]) continue;//如果另一种药水没被拿过,我们不能确定现在他的距离是最小的
          if (dist[v.s]>qf+dist[v.f]){
            dist[v.s] = qf+dist[v.f];
            ways[v.s] = ways[v.f]*ways[qs];
            q.push(make_pair(-dist[v.s],v.s));//刚刚讲过的转移
          }else if (dist[v.s]==qf+dist[v.f]){
            ways[v.s] += ways[v.f]*ways[qs];
          }
        }
      }
      cout << dist[0] << " " <<ways[0];//答案
    }
    
  • 相关阅读:
    /etc/sysctl.conf 控制内核相关配置文件
    python 并发编程 非阻塞IO模型
    python 并发编程 多路复用IO模型
    python 并发编程 异步IO模型
    python 并发编程 阻塞IO模型
    python 并发编程 基于gevent模块 协程池 实现并发的套接字通信
    python 并发编程 基于gevent模块实现并发的套接字通信
    python 并发编程 io模型 目录
    python 并发编程 socket 服务端 客户端 阻塞io行为
    python 并发编程 IO模型介绍
  • 原文地址:https://www.cnblogs.com/DannyXu/p/12536356.html
Copyright © 2011-2022 走看看