题解: 裸最短路 存一下手写堆优化的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算法。