zoukankan      html  css  js  c++  java
  • BZOJ3040: 最短路(road)

    题解: 裸最短路 存一下手写堆优化的dij的板子

    #include <bits/stdc++.h>
    #define ll long long
    #define link(x) for(edge *j=h[x];j;j=j->next)
    const int NM=1e7+10;
    const int nm=1e6+10;
    const ll inf=9e18;
    using namespace std;
    struct FastIO
    {
        static const int S=200;
        int wpos;
        char wbuf[S];
        FastIO():wpos(0){}
        inline int xchar()
        {
            static char buf[S];
            static int len=0,pos=0;
            if(pos==len) pos=0,len=fread(buf,1,S,stdin);
            if(pos==len) exit(0);
            return buf[pos++];
        }
        inline int read()
        {
            int s=1,c=xchar(),x=0;
            while(c<=32) c=xchar();
            if(c=='-') s=-1,c=xchar();
            for(;'0'<=c&&c<='9';c=xchar()) x=x*10+c-'0';
            return x*s;
        }
        ~FastIO()
        {
            if(wpos) fwrite(wbuf,1,wpos,stdout),wpos=0;
        }
    }io;
    struct edge{int t;ll vul;edge*next;}e[NM],*h[nm],*o=e;
    void add(int x,int y,ll vul){o->t=y;o->vul=vul;o->next=h[x];h[x]=o++;}
    int n,m,t;
    int rxa,rxc,rya,ryc,rp,x,y,z;ll dis[nm];
    struct Heap{
    	int num[nm],pos[nm],size;
    	
    	void PushUp(int p) {
    		while(p > 1) {
    			if(dis[num[p]] < dis[num[p >> 1]]) {
    				swap(num[p],num[p >> 1]);
    				swap(pos[num[p]],pos[num[p >> 1]]);
    				p >>= 1;
    			}
    			else break;
    		}
    	}
    	void Insert(long long x) {
    		num[++size] = x;
    		pos[x] = size;
    		PushUp(size);
    	}
    	void Pop() {
    		pos[num[1]] = 0;
    		num[1] = num[size--];
    		if(size) pos[num[1]] = 1;
    		int now = 2;
    		while(now < size) {
    			if(dis[num[now + 1]] < dis[num[now]])
    				++now;
    			if(dis[num[now]] < dis[num[now >> 1]]) {
    				swap(num[now],num[now >> 1]);
    				swap(pos[num[now]],pos[num[now >> 1]]);
    				now <<= 1;
    			}
    			else break;
    		}
    	}
    }heap;
    void dij(int p){
    	for(int i=1;i<=n;i++)dis[i]=inf,heap.Insert(i);
    	dis[p]=0;
    	while(heap.size){
    		int t1=heap.num[1];heap.Pop();
    		link(t1){
    			if(dis[j->t]>dis[t1]+j->vul){
    				dis[j->t]=dis[t1]+j->vul;
    				heap.PushUp(heap.pos[j->t]);
    			}
    		}
    	}
    }
    int main(){
    	n=io.read();m=io.read();
    	t=io.read();rxa=io.read();rxc=io.read();rya=io.read();ryc=io.read();rp=io.read();
    	x=0;y=0;z=0;int u,v;int vul;
    	for(int i=1;i<=t;i++){
    		x=(1LL*x*rxa+rxc)%rp;y=(1LL*y*rxa+rxc)%rp;
    		u=min(x%n+1,y%n+1);v=y%n+1;vul=100000000-100*u;
    		if(u!=v)add(u,v,vul);
    	}
    	for(int i=1;i<=m-t;i++)u=io.read(),v=io.read(),vul=io.read(),add(u,v,vul);
    	dij(1);
    	printf("%lld
    ",dis[n]);
    	return 0;
    }	
    

    3040: 最短路(road)

    Time Limit: 60 Sec  Memory Limit: 200 MB
    Submit: 4153  Solved: 1335
    [Submit][Status][Discuss]

    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算法。

  • 相关阅读:
    深入剖析ASP.NET的编译原理之一:动态编译(Dynamical Compilation)
    ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline Part I
    IIS Server Variables(IIS 服务器变量)
    .Net源码之Page类(二)
    博客改变生活
    目录、路径、虚拟路径
    Windows 7 Beta 1 7000
    《Visual Studio Hacks 》读书笔记 (十二)
    新建XML文件
    另一个分页函数
  • 原文地址:https://www.cnblogs.com/wang9897/p/9479131.html
Copyright © 2011-2022 走看看