前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2019中国大学生程序设计竞赛(CCPC)---网络选拔赛-1004-path

2019中国大学生程序设计竞赛(CCPC)---网络选拔赛-1004-path

作者头像
xiaohejun
发布2020-02-18 09:16:08
3980
发布2020-02-18 09:16:08
举报
文章被收录于专栏:xiaohejun的算法知识分享

考虑维护按照边权最小的堆,维护结点信息如下:

代码语言:javascript
复制
int u; // 上一个结点
int v; // 当前结点
LL lst; // 到上一个结点u的距离
LL now; // 到当前结点v的距离
int id; // 上一个结点u下一次需要扩展的下标

一开始,先将每个结点从最短的那条边扩展,然后对于每次操作。取队头元素,当前的路径距离就是第$idx$小的路径,用队头元素进行扩展:

  1. 从结点$v$最短的一条边扩展
  2. 从结点u的$id$下标编号进行扩展

扩展的时候维护上述信息。

这种贪心策略就是很对。

代码语言:javascript
复制
#include <bits/stdc++.h>
using namespace std;
 
typedef long long LL;
#define dbg(x) cout << #x"=" << x << endl;
#define SZ(x) (int)(x).size()

struct Node{
    int u; // 上一个结点
    int v; // 当前结点
    LL lst; // 到上一个结点u的距离
    LL now; // 到当前结点v的距离
    int id; // 上一个结点u下一次需要扩展的下标
    bool operator<(const Node &b)const{
        return now > b.now;
    }
    void pt(){
        dbg(u)
        dbg(v)
        dbg(lst)
        dbg(now)
        dbg(id)
        dbg("----")
    }
};

typedef pair<LL, int> P;
#define w_ first 
#define v_ second
const int MAX_M = 5*1e4+100;
int Q[MAX_M], A[MAX_M];
int n,m,q;
vector<P> G[MAX_M];

void solve(){
    cin >> n >> m >> q;
    for(int i = 1; i <= n; ++i) G[i].clear();
    int u,v;
    LL w;
    priority_queue<Node> que;
    for(int i = 1; i <= m; ++i){
        cin >> u >> v >> w;
        G[u].push_back(make_pair(w, v));
    }
    int mxK = 0;
    for(int i = 1; i <= q; ++i){
        cin >> Q[i];
        mxK = max(mxK, Q[i]);
    }
    for(int i = 1; i <= n; ++i){
        sort(G[i].begin(), G[i].end());
        if(SZ(G[i])){ // 从G[i]最小的扩展出一条边
            P e = G[i][0];
            que.push((Node){i, e.v_, 0, e.w_, 1});
        }
    }
    int idx = 0;
    /*
    int u; // 上一个结点
    int v; // 当前结点
    LL lst; // 到上一个结点u的距离
    LL now; // 当当前结点v的距离
    int id; // 上一个结点u需要扩展的下标
    */
    while(idx < mxK){
        Node p = que.top(); 
        que.pop();
        A[++idx] = p.now;
        // 从v扩展当前结点最小的边
        if(SZ(G[p.v])) { 
            P e = G[p.v][0];
            que.push((Node){p.v, e.v_, p.now, p.now+e.w_, 1});
        }
        // 通过G[p.u][p.id]扩展
        if(p.id < SZ(G[p.u])){
            P e = G[p.u][p.id];
            que.push((Node){p.u, e.v_, p.lst, p.lst+e.w_, p.id+1});
        }
    }
    for(int i = 1; i <= q; ++i){
        cout << A[Q[i]] << endl;
    }
}

int main(){
	//freopen("in.txt", "r", stdin);
	ios::sync_with_stdio(0); cin.tie(0);
    int T;
    cin >> T;
    while(T--) solve();
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-03-242,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档