zoukankan      html  css  js  c++  java
  • HDU

    path hdu-6705

    题意:给你一幅有向图,给你q个数k ,问你在这幅图上第k短的路径有多长。
    思路:首先有q个询问,且没有出现修改操作,考虑离线处理。然后我们可以用一个vector储存所有的边。并把每个节点的出边按从小到大排序。接下来求出所有询问的最大值maxk,然后我们只要求第1~maxk的短路即可。然后先把所有边都存入一个set,并且这个set是按照路径长短排序的。接下来保证这个set里的元素有maxk个,然后用类似于Djikstra求最短路的方法不断去set中的内容即可,第i次从set的头部弹出的就是第i短路。
    代码:

    const int maxn=5e5+5;
    ll ans[maxn];
    int n,m,k,cur[maxn],cnt=0;
    struct node{
        int v;ll w;
        node (int v = 0, int w = 0): v(v), w(w) {}
        bool operator < (const node &b) const {
            return w<b.w;
        }
    };
    vector<node>G[maxn];
    struct Edge{
        int u,v;
        ll w;
        int id;
        Edge(int u = 0, int v = 0, ll w = 0, int id = 0): u(u), v(v), w(w), id(id) {}
        bool operator <(const Edge &b)const{
            if(w==b.w){
                if(u==b.u){
                    if(v==b.v){
                        return id<b.id;
                    }else{
                        return v<b.v;
                    }
                }else{
                    return u<b.u;
                }
            }else{
                return w<b.w;
            }
        }
        bool operator == (const Edge &b) const {
            return w == b.w && u == b.u && v == b.v && id == b.id;
        }
    
    };
    int main()
    {
        int T;
        cin>>T;
        while(T--){
            scanf("%d %d %d",&n,&m,&k);
            for(int i=1;i<=n;i++){
                G[i].clear();
            }
            set<Edge>st;
            st.clear();
            cnt=0;
            for(int i=1;i<=m;i++){
                int u,v;
                ll w;
                scanf("%d%d%lld",&u,&v,&w);
                G[u].push_back(node(v,w));
                st.insert(Edge(u,v,w,++cnt));
            }
            for(int i=1;i<=n;i++){
                sort(G[i].begin(),G[i].end());
            }
            int maxk=0;
            for(int i=1;i<=k;i++){
                scanf("%d",&cur[i]);
                maxk=max(maxk,cur[i]);
            }
            while(st.size()>maxk){
                st.erase(st.end());
            }
            for(int i=1;i<=maxk;i++){
                Edge now=*st.begin();
                st.erase(st.begin());
                ans[i]=now.w;
                if(i==maxk)break;
                int u=now.v;
                for(int j=0;j<G[u].size();j++){
                    int v=G[u][j].v;
                    ll w=G[u][j].w;
                    if(st.size()+i<maxk){
                        st.insert(Edge(u,v,now.w+w,++cnt));
                    }else{
                        set<Edge>::iterator it = st.end();
                        it--;
                        Edge last=*it;
                        if(last.w>w+now.w){
                            st.erase(it);
                            st.insert(Edge(u,v,w+now.w,++cnt));
                        }else{
                            break;
                        }
                    }
                }
    
            }
            for(int i=1;i<=k;i++){
                printf("%lld
    ",ans[cur[i]]);
            }
        }
        return 0;
    }
    
    
    越自律,越自由
  • 相关阅读:
    js 时间戳格式化
    有关Safari 浏览器的文章
    前端图片旋转动画
    vue中textarea标签自适应高度
    pip 报错 Fatal error in launcher: Unable to create process using
    HTML列表多点击事件
    js获取浏览器版本信息
    SVG圆形进度条
    基于蚂蚁金服"AntDesignVue-Menu导航菜单"实现根据初始路由自动选中对应菜单解决刷新后菜单选择状态丢失问题(支持根路径菜单)
    java根据权重进行排序
  • 原文地址:https://www.cnblogs.com/ha-chuochuo/p/13635445.html
Copyright © 2011-2022 走看看