zoukankan      html  css  js  c++  java
  • 基里巴斯(path)

    基里巴斯(path)

    题目描述

    最近,帕特里克沉迷于世界地图上的太平洋地区。他发现了一个名字奇异的岛国:基里巴斯共和国,简称基里巴斯,是一个太平洋岛国。

    其由33个岛屿组成。

    “可惜它快被淹没了,该死的全球变暖”。

    真悲哀。

    我们这里讨论其在四维平行宇宙中的另一个国家:巴里基斯。这个国家由NN个岛屿或岛礁组成。

    由于岛屿众多,政府在所有的岛屿之间均设有固定的经济航线连接。对于编号为u,v的岛屿(u,v)对,连接两岛的单向航线通行费用是(u⊕v)×K。其中,⊕表示异或(Xor)。

    泛美航空公司开设了MM条往返于各岛的单向航线,每条航线均有一个固定的通行费用以期以更低的价格占有更多的用户群。

    另外,泛美打算在岛礁中心建设了一个机场作为中转枢纽,这个枢纽建成后或许能大大降低泛美的航空成本。但是作为邪恶的资本主义财团,董事长还是希望调研一下收益。

    于是,他打算从SS飞到城市TT。他希望得知从SS到城市TT的最小费用。

    输入

    输入第一行包含三个整数N,M,K,含义如题所示。

    接下来MM行,每行三个整数ui,vi,wi描述一条单向航线。

    最后一行两个整数S,T,表示想要调研的起点和终点。

    输出

    输出包含一个整数,为从SS到城市TT的最小费用。

    样例输入

    【样例1输入】
    5 3 3
    1 3 2
    2 4 4
    2 3 2
    1 5
    【样例2输入】
    1000 1 85
    829 630 1
    633 492

    样例输出

    【样例1输出】
    12
    【样例2输出】
    77945

    提示

    对于所有测试数据,保证:1≤K≤103,1≤wi≤105,1≤ui,vi≤n1≤K≤103,1≤wi≤105,1≤ui,vi≤n

    详细部分分见下表:

    测试点

    N

    M

    1

     ≤105≤105 

    =0

    2

    =1

    3

    =2

    4

    =3

    5

    =10

    6-7

    ≤103≤103  

    8-10

    ≤103≤103

    11-20

    ≤2×105≤2×105

    ≤106≤106

    数据不保证无重边。

    来源

    lhy

    solution

    对于点i

    把每一位分离出来

    若i的着一位为0 则lj(i,i+(1<<j))

    若为1 则lj(i,i-(1<<j))

    这样就能走遍所有点,边数nlogn+m

    这题卡spfa。。。

    很久没写dijkstra,忘光

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define maxn 200005
    #define inf 1e9
    using namespace std;
    int n,m,K,tot,t1,t2,t3,head[maxn],S,T;
    int d[maxn];
    struct node{
        int v,nex;
        int w;
    }e[8000005];
    struct no{
        int x,v;
        bool operator <(const no &T)const{return v>T.v;}
    };
    priority_queue<no>q;
    void lj(int t1,int t2,int t3){
        e[++tot].v=t2;e[tot].w=t3;e[tot].nex=head[t1];head[t1]=tot;
    }
    bool flag[maxn];
    int main()
    {
        cin>>n>>m>>K;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&t1,&t2,&t3);
            lj(t1,t2,t3);
        }
        cin>>S>>T;
        for(int i=1;i<=n;i++){
            for(int j=0;j<=22;j++){
                if(i&(1<<j)){
                    int ne=i-(1<<j);
                    if(ne<=n)lj(i,ne,(1<<j)*K);
                }
                else {
                    int ne=i+(1<<j);
                    if(ne<=n)lj(i,ne,(1<<j)*K);
                }
            }
        }
        for(int i=1;i<=n;i++)d[i]=inf;
        d[S]=0;no t;t.x=S,t.v=0;
        q.push(t);
        for(int i=1;i<=n;i++){
            if(q.empty())break;
            no k;
            while(flag[q.top().x]&&!q.empty())q.pop();
            if(!q.empty())k=q.top();
            else break;
            flag[k.x]=1;
            if(k.x==T)break;
            for(int i=head[k.x];i;i=e[i].nex){
                if(d[e[i].v]>d[k.x]+e[i].w&&!flag[e[i].v]){
                    d[e[i].v]=d[k.x]+e[i].w;
                    t.x=e[i].v,t.v=d[e[i].v];
                    q.push(t);
                }
            }
        }
        cout<<d[T]<<endl;
        return 0;
    }
     
  • 相关阅读:
    常见设计模式,总结的不错(转)
    mysql查询当前时间,一天内,一周,一个月内的sql语句
    PBOC金融IC卡,卡片与终端交互的13个步骤,简介-第一组(转)
    金融IC卡 ARQC和ARPC计算方法和实例(转)
    如何解决结果由block返回情况下的同步问题(转)
    linux进程编程:子进程创建及执行函数简介
    exec函数族实例解析
    C语言中system()函数的用法总结(转)
    关于JSPatch热修复
    做个这样的APP要多久?[转]
  • 原文地址:https://www.cnblogs.com/liankewei/p/10358867.html
Copyright © 2011-2022 走看看