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\n",dis[n]); return 0; }
3040: 最短路(road)
Time Limit: 60 Sec Memory Limit: 200 MBSubmit: 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
0 1 2 3 5 7
1 2 1
1 3 3
2 3 1
Sample Output
2
HINT
【注释】
请采用高效的堆来优化Dijkstra算法。