• BZOJ-3040-最短路(road)


    Description

    N个点,M条边的有向图,求点1到点N的最短路(保证存在)。
    1<=N<=1000000,1<=M<=10000000

    Input


    第一行两个整数N、M,表示点数和边数。
    第二行六个整数T、rxa、rxc、rya、ryc、rp。

    前T条边采用如下方式生成:
    1.初始化x=y=z=0。
    2.重复以下过程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);
    则有一条从a到b的,长度为1e8-100*a的有向边。

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

    1<=x,y<=N,0<z,rxa,rxc,rya,ryc,rp<2^31

    Output


    一个整数,表示1~N的最短路。

    Sample Input

    3 3
    0 1 2 3 5 7
    1 2 1
    1 3 3
    2 3 1

    Sample Output

    2

    HINT

    【注释】

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


    Source

     

    题解

    这道题正解要用配对堆

    但其实stl的普通堆也可以卡过,重点是卡过

    自己不知道RE和TLE了多久


    AC代码:

    RE代码:

    这样我还能说什么0.0

     1 #include<queue>
     2 #include<cstdio>
     3 #include<algorithm> 
     4 #define ll long long
     5 #define zcr pair<int,int>
     6 using namespace std;
     7 int tot;
     8 int next[10000005],head[1000005],son[10000005],val[10000005];
     9 ll dis[1000005];
    10 bool vis[1000005];
    11 int read(){
    12     int tmp=0; char ch=getchar();
    13     while (ch<'0'||ch>'9') ch=getchar();
    14     while (ch>='0'&&ch<='9') tmp=tmp*10+ch-'0',ch=getchar();
    15     return tmp;
    16 }
    17 void add(int x,int y,int z){
    18     next[++tot]=head[x];
    19     head[x]=tot;
    20     son[tot]=y;
    21     val[tot]=z;
    22 }
    23 priority_queue<zcr,vector<zcr>,greater<zcr> > q;
    24 int main(){
    25     int n,m;
    26     n=read(),m=read();
    27     int T,rxa,rxc,rya,ryc,rp;
    28     T=read(),rxa=read(),rxc=read(),rya=read(),ryc=read(),rp=read();
    29     int a,b,x,y;
    30     for (int i=1;i<=T;i++){
    31         x=(x*rxa+rxc)%rp;
    32         y=(y*rya+ryc)%rp;
    33         a=min(x%n+1,y%n+1);
    34         b=max(y%n+1,y%n+1);
    35         add(a,b,100000000-100*a);
    36     }
    37     for (int i=1;i<=m-T;i++){
    38         int u=read(),v=read(),s=read();
    39         add(u,v,s);
    40     }
    41     for (int i=1;i<=n;i++) dis[i]=1ll<<50;
    42     dis[1]=0;
    43     q.push(make_pair(0,1));
    44     while (!q.empty()){
    45         int x=q.top().second;
    46         q.pop();
    47         if (vis[x]) continue;
    48         vis[x]=true;
    49         for (int i=head[x];i;i=next[i]){
    50             int v=son[i];
    51             if (dis[v]>dis[x]+val[i]){
    52                 dis[v]=dis[x]+val[i];
    53                 q.push(make_pair(dis[v],v));
    54             }
    55         }
    56     }
    57     printf("%d
    ",dis[n]);
    58     return 0;
    59 } 
    View Code
  • 相关阅读:
    台州 OJ 3847 Mowing the Lawn 线性DP 单调队列
    洛谷 OJ P1417 烹调方案 01背包
    快速幂取模
    台州 OJ 2649 More is better 并查集
    UVa 1640
    UVa 11971
    UVa 10900
    UVa 11346
    UVa 10288
    UVa 1639
  • 原文地址:https://www.cnblogs.com/zhuchenrui/p/7701404.html
Copyright © 2020-2023  润新知