zoukankan      html  css  js  c++  java
  • BZOJ 3040最短路

    题目描述

    给定一个 NN 个点, MM 条有向边的带权图,请你计算从 SS 出发,到每个点的距离。

    数据保证你能从 SS 出发到任意点。

    输入输出格式

    输入格式:

     

    第一行两个整数 NN 、 MM ,表示点数和边数。 第二行六个整数 TT 、 rxarxa 、 rxcrxc 、 ryarya 、 rycryc 、 rprp 。

    前 TT 条边采用如下方式生成:

    1. 初始化 x=y=z=0x=y=z=0 。
    2. 重复以下过程 TT 次:
      x=(x*rxa+rxc)%rp;
      y=(y*rya+ryc)%rp;
      a=min(x%n+1,y%n+1);
      b=max(y%n+1,y%n+1);

      则有一条从 aa 到 bb 的,长度为 1e8-100*a1e8100a 的有向边。

    后 M-TMT 条边采用读入方式: 接下来 M-TMT 行每行三个整数 x,y,zx,y,z ,表示一条从 xx 到 yy 长度为 zz 的有向边。

     

    输出格式:

     

    一个整数,表示 11 到 NN 的最短路。

     

    输入输出样例

    输入样例#1: 
    3 3
    0 1 2 3 5 7
    1 2 1
    1 3 3
    2 3 1
    输出样例#1: 
    2

    说明

    1leq Nleq 10^61N106 , 1leq Mleq 10^71M107

    1leq x,yleq N1x,yN , 0<z,rxa,rxc,rya,ryc,rp<2^{31}0<z,rxa,rxc,rya,ryc,rp<231

    请采用高效的堆来优化Dijkstra算法。

    Solution:

      本题实在是毒瘤,而且内存限制还卡的那么死。

      思路还是比较正常的堆优化dijkstra,只不过我们用的是更高效的配对堆(pbds中的配对堆)。

      然后坑点就是空间很死,为了防止重复入队,我们记录一下堆中每个元素的迭代器,然后在三角不等式更新后直接判断该节点是否已在堆中,若在就直接modify修改值,否则才入队,这样能保证堆中元素不超过$N$。

    代码:

    #include<bits/stdc++.h>
    #include<ext/pb_ds/assoc_container.hpp>
    #include<ext/pb_ds/priority_queue.hpp>
    #define il inline
    #define ll long long
    #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
    #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
    using namespace std;
    using namespace __gnu_pbds;
    const int N=1000005,M=10000000;
    const ll inf=100000000000000000;
    int n,m,s,to[M+5],w[M+5],h[N],net[M+5],cnt;
    ll dis[N];
    int T,rxa,rxc,rya,ryc,rp;
    bool vis[N];
    struct node{
        int u;ll d;
        node(int a=0,ll b=0){u=a,d=b;}
        bool operator<(const node &a)const {return d>a.d;}
    };
    typedef __gnu_pbds::priority_queue<node,less<node>,pairing_heap_tag> heap;
    
    heap q;
    heap::point_iterator id[N];
    
    il int gi(){
        int a=0;char x=getchar();
        while((x<'0'||x>'9')&&x!='-')x=getchar();
        while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar();
        return a;
    }
    
    il void add(int u,int v,int c){to[++cnt]=v,net[cnt]=h[u],h[u]=cnt,w[cnt]=c;}
    
    il void spfa(){
        For(i,2,n) dis[i]=inf;
        dis[s]=0,q.push(node(s,0));
        while(!q.empty()){
            node x=q.top();q.pop();
            int u=x.u;
            if(vis[u])continue;
            vis[u]=1;
            for(int i=h[u];i;i=net[i])
                if(dis[to[i]]>dis[u]+w[i]){
                    dis[to[i]]=dis[u]+w[i];
                    if(id[to[i]]==0)id[to[i]]=q.push(node(to[i],dis[to[i]]));
                    else q.modify(id[to[i]],node(to[i],dis[to[i]]));
                }
        }
    }
    
    int main(){
        n=gi(),m=gi(),T=gi(),rxa=gi(),rxc=gi(),rya=gi(),ryc=gi(),rp=gi(),s=1;
        ll x=0,y=0,z=0,a,b;
        m-=T;
        For(i,1,T){
            x=(x*rxa+rxc)%rp,
            y=(y*rya+ryc)%rp,
            a=min(x%n+1,y%n+1),
            b=max(y%n+1,y%n+1);
            add(a,b,100000000-100*a);
        }
        For(i,1,m) x=gi(),y=gi(),z=gi(),add(x,y,z);
        spfa();
        cout<<dis[n];
        return 0;
    }
  • 相关阅读:
    zoj 3279 线段树 OR 树状数组
    fzu 1962 树状数组 OR 线段树
    hdu 5057 块状链表
    hdu3487 Play with Chain
    bzoj 1588营业额统计(HNOI 2002)
    poj2823 Sliding Window
    poj2828 Buy Tickets
    poj2395 Out of Hay
    poj3667 Hotel
    poj1703 Lost Cows
  • 原文地址:https://www.cnblogs.com/five20/p/9360838.html
Copyright © 2011-2022 走看看