zoukankan      html  css  js  c++  java
  • 2019ccpc网络赛hdu6705 path

    path

    题目传送门

    解题思路

    先用vector存图,然后将每个vector按照边的权值从小到大排序。将每个顶点作为起点的边里最短的边存入优先队列。对于存入优先队列的信息,应有边起点,终点,是其起点的第几短边,以及路径总长度。优先队列按照路径长度从小到大排序,每次出队当前最短的路径,对于一条路径,更新两条新的可能最短的路径,即这条路后面加上一条可走的最短边,以及这条路最后一条边换成一条次短边。将询问排序,不断更新答案即可。

    代码如下

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    
    const int N = 100010;
    
    struct T{
        int x, y, f;
        ll w;
        T(int x, int y, ll w, int f): x(x), y(y), w(w), f(f){}
        bool operator<(const T& a)const{
            return w > a.w;
        }
    };
    
    struct line{
        int r;
        ll w;
        line(int r, ll w): r(r), w(w){}
        bool operator<(const line& a)const{
            return w < a.w;
        }
    };
    vector<line> vec[N];
    struct R{
        int i, k;
        bool operator<(const R& a)const{
            return k < a.k;
        }
    }qy[N];
    ll ans[N];
    priority_queue<T> pq;
    
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t --){
            int n, m, q;
            scanf("%d%d%d", &n, &m, &q);
            for(int i = 1; i <= m; i ++){
                int u, v;
                ll w;
                scanf("%d%d%lld", &u, &v, &w);
                vec[u].push_back(line(v, w));
            }
            for(int i = 1; i <= n; i ++){
                sort(vec[i].begin(), vec[i].end());
            }  
            for(int i = 1; i <= n; i ++){
                if(vec[i].size())
                    pq.push(T(i, vec[i][0].r, vec[i][0].w, 0));
            }
            for(int i = 1; i <= q; i ++){
                scanf("%d", &qy[i].k);
                qy[i].i = i;
            }
            sort(qy + 1, qy + q + 1);
            int cnt = 0;
            int id = 1;
            while(!pq.empty()){
                int x = pq.top().x;
                int y = pq.top().y;
                ll w = pq.top().w;
                int f = pq.top().f;
                pq.pop();
                ++cnt;
                while(id <= q && cnt == qy[id].k){
                    ans[qy[id].i] = w;
                    ++id;
                }
                if(id > q)
                    break;
                if(vec[y].size())
                    pq.push(T(y, vec[y][0].r, w + vec[y][0].w, 0));
                if(vec[x].size() > f + 1)
                    pq.push(T(x, vec[x][f + 1].r, w + vec[x][f + 1].w - vec[x][f].w, f + 1));
            }
            for(int i = 1; i <= q; i ++){
                printf("%lld
    ", ans[i]);
            }
            for(int i = 0; i <= n; i ++)
                vec[i].clear();
            while(!pq.empty())
                pq.pop();
        }
        return 0;
    }
    
  • 相关阅读:
    聊聊Senior .net 面试,作为面试官你称职吗
    使用Microsoft BizTalk Adapter for mySAP Business Suite需要注意的一些限制点
    eos账号管理
    如何安装以太坊钱包Parity
    Infoq主办 Baidu Web 开发者大会记录
    http请求的详细过程转载
    php 下载保存文件保存到本地
    php section
    用javascript拼接html代码标签
    php使用sql数据库 取得字段问题
  • 原文地址:https://www.cnblogs.com/whisperlzw/p/11403890.html
Copyright © 2011-2022 走看看