• 题解 P4366 【[Code+#4]最短路】


    题目链接

    Solution [Code+#4]最短路

    题目大意:图上任意两点(u,v)间有权值为((u;xor;v) imes c)的无向边,再添加给定的(m)条有向边之后,询问(s)(t)的最短路

    最短路


    分析:首先给定的有向边我们肯定直接连上,剩下的无向边规模极大直接跑最短路会炸掉

    我们考虑去除无用的边,如果当前点为(u),就将(u)与和它二进制表示只有一位不同的(v)连边。如果((u,v))直接的连边被去掉了,它可以通过图上路径表示出来,不会影响正确性

    边的规模便可以降到(O(nlogn))

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <vector>
    #include <queue>
    using namespace std;
    const int maxn = 1e5 + 100;
    inline int read(){
        int x = 0;char c = getchar();
        while(!isdigit(c))c = getchar();
        while(isdigit(c))x = x * 10 + c - '0',c = getchar();
        return x;
    }
    struct edge{int v,d;};
    vector<edge> G[maxn];
    inline void addedge(int u,int v,int d){
        G[u].push_back(edge{v,d});}
    int vis[maxn],dis[maxn],n,m,c,s,t;
    struct node{
        int u,h;
        bool operator < (const node &rhs)const{
            return h > rhs.h;
        }
    };
    priority_queue<node> Q;
    inline void dijkstra(int s){
        memset(dis,0x3f,sizeof(dis));
        dis[s] = 0;Q.push(node{s,0});
        while(!Q.empty()){
            int u = Q.top().u;Q.pop();
            if(vis[u])continue;
            vis[u] = 1;
            for(auto e : G[u]){
                if(dis[u] + e.d < dis[e.v]){
                    dis[e.v] = dis[u] + e.d;
                    Q.push(node{e.v,dis[e.v]});
                }
            }
            for(int i = 20;i >= 0;i--)
                if((u ^ (1 << i)) <= n && (dis[u] + (1 << i) * c) < dis[u ^ (1 << i)]){
                    dis[u ^ (1 << i)] = dis[u] + (1 << i) * c;
                    Q.push(node{u ^ (1 << i),dis[u ^ (1 << i)]});
                }
        }
    }
    int main(){
        n = read(),m = read(),c = read();
        for(int u,v,d,i = 1;i <= m;i++)
            u = read(),v = read(),d = read(),addedge(u,v,d);
        s = read(),t = read();
        dijkstra(s);
        printf("%d
    ",dis[t]);
        return 0;
    }
    
  • 相关阅读:
    AutoLayout动画
    实现毛玻璃效果
    合并静态库
    GCDAsyncSocket~
    iOS下URL编码
    OC多线程之GCD ----- 2
    堆和栈的区别
    Effective Objective-C 2.0重读笔记---2
    Android手机端抓包方法
    Android APK反编译
  • 原文地址:https://www.cnblogs.com/colazcy/p/13537633.html
Copyright © 2020-2023  润新知