• [Code+#4]最短路 (最短路)


    [Code+#4]最短路

    题目背景

    在北纬 91° ,有一个神奇的国度,叫做企鹅国。这里的企鹅也有自己发达的文明,称为企鹅文明。因为企鹅只有黑白两种颜色,所以他们的数学也是以二进制为基础发展的。

    比如早在 1110100111101001 年前,他们就有了异或这样一个数学概念。如果你不知道异或是什么,请出门过墙左转到这里

    再比如早在 10000101000010 年前,他们的大科学家 Penguin. Tu 就提出了最短路径这样一些概念。

    题目描述

    企鹅国中有 N 座城市,编号从 1 到 N 。

    对于任意的两座城市 i 和 j ,企鹅们可以花费 ((i~mathrm{xor}~j) imes C) 的时间从城市 i 走到城市 j ,这里 C 为一个给定的常数。

    当然除此之外还有 (M) 条单向的快捷通道,第 (i) 条快捷通道从第 (F_i) 个城市通向第 (T_i)​​​ 个城市,走这条通道需要消耗 (V_i)​​​ 的时间。

    现在来自 Penguin Kingdom University 的企鹅豆豆正在考虑从城市 A 前往城市 B 最少需要多少时间?

    输入输出格式

    输入格式:

    从标准输入读入数据。

    输入第一行包含三个整数 (N,M,C) ,表示企鹅国城市的个数、快捷通道的个数以及题面中提到的给定的常数CC。

    接下来的 M 行,每行三个正整数 (F_i,T_i,V_i (1≤Fi​≤N,1 leq T_i leq N ,1leq V_i leq 100)),分别表示对应通道的起点城市标号、终点城市标号和通过这条通道需要消耗的时间。

    最后一行两个正整数 A,B ((1 leq C leq 100)),表示企鹅豆豆选择的起点城市标号和终点城市标号。

    输出格式:

    输出到标准输出。

    输出一行一个整数,表示从城市 A 前往城市 B 需要的最少时间。

    输入输出样例

    输入样例#1: 复制

    4 2 1
    1 3 1
    2 4 4
    1 4

    输出样例#1: 复制

    5

    输入样例#2: 复制

    7 2 10
    1 3 1
    2 4 4
    3 6

    输出样例#2: 复制

    34

    说明

    样例1解释

    直接从 1 走到 4 就好了。

    样例2解释

    先从 3 走到 2 ,再从 2 通过通道到达 4 ,再从 4 走到 6。

    0

    题解

    一道思路非常巧妙的题目。
    在这里我们要充分利用到异或的性质。
    我们知道如果 A^ B ^ C ^ D =A^E时。
    就直接建边A->E了。
    也就是说,有些边是多余的。
    那么我们怎么确保必要的边呢?
    一个点到只需要连接n的每一个二进制的1就可以了。
    因为所有的异或情况都可以由二进制组合出来。
    那么边就是(m+log(n))的。

    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=4000001;
    struct node{
        int to,v,nex;
    }e[N];
    int num,head[N];
    int n,m,c,s,t,dis[N],vis[N];
    int read(){
    
        int x=0,w=1;char ch=getchar();
        while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*w;
    }
    
    void add(int from,int to,int v){
        num++;
        e[num].to=to;
        e[num].v=v;
        e[num].nex=head[from];
        head[from]=num;
    }
    
    void dijkstra(){
        priority_queue<pair<int,int> >q;
        memset(dis,63,sizeof(dis));dis[s]=0;
        q.push(make_pair(-dis[s],s));
        while(!q.empty()){
            int u=q.top().second;q.pop();
            if(vis[u])continue;vis[u]=1;
            for(int i=head[u];i;i=e[i].nex){
                int v=e[i].to;
                if(dis[v]>dis[u]+e[i].v){
                    dis[v]=dis[u]+e[i].v;
                    q.push(make_pair(-dis[v],v));
                }
            }
        }
    }
    
    int main(){
        n=read();m=read();c=read();
        for(int i=1;i<=m;i++){
            int x=read(),y=read(),z=read();
            add(x,y,z);
        }
        for(int i=0;i<=n;i++){
            for(int j=1;j<=n;j<<=1){
                if((j^i)>n)continue;
                add(i,(i^j),j*c);
            }
        }
        s=read();t=read();
        dijkstra();
        printf("%d
    ",dis[t]);
        return 0;
    }
    
  • 相关阅读:
    学习ASP.NET Web API框架揭秘之“HTTP方法重写”
    学习、摘录、目标——学习任务
    ASP.NET Core学习零散记录
    通过Nginx实现负载均衡
    通过IIS共享文件夹来实现静态资源"本地分布式"部署
    python2.7 django 错误汇总
    【心得】算法练习
    【数据结构】思维导图
    【算法】思维导图
    记录一次面试中二分查找的算法题
  • 原文地址:https://www.cnblogs.com/hhh1109/p/9588741.html
Copyright © 2020-2023  润新知