3040: 最短路(road)
Time Limit: 60 Sec Memory Limit: 200 MBSubmit: 2333 Solved: 773
[ 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算法。
Source
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#include<ext/pb_ds/priority_queue.hpp>
const int maxn = 1E6 + 5;
typedef long long LL;
const LL K = 1E8;
#define pr pair<LL, int>
#define pb push_back
#define mp make_pair
#define sc second
#define ft first
using namespace std;
typedef __gnu_pbds::priority_queue<pr,greater<pr>,__gnu_pbds::pairing_heap_tag> heap;
struct E{
int to,w;
E(int _to = 0,int _w = 0) {to = _to; w = _w;}
};
LL n,m,T,rxa,rxc,rya,ryc,rp;
LL dis[maxn];
vector <E> v[maxn];
heap::point_iterator id[maxn];
heap Q;
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
cin >> n >> m >> T >> rxa >> rxc >> rya >> ryc >> rp;
LL x,y,z; x = y = z = 0;
for (int i = 1; i <= T; i++) {
x=(x*rxa+rxc)%rp;
y=(y*rya+ryc)%rp;
int a=min(x%n+1,y%n+1);
int b=max(y%n+1,y%n+1);
v[a].push_back(E(b,100000000 - 100*a));
}
for (int i = 1; i <= m - T; i++) {
int a,b,c; scanf("%d%d%d",&a,&b,&c);
v[a].push_back(E(b,c));
}
dis[1] = 0; id[1] = Q.push(mp(0,1));
while (!Q.empty()) {
int k = Q.top().sc; Q.pop();
for (int i = 0; i < v[k].size(); i++) {
int to = v[k][i].to;
LL w = v[k][i].w;
if (dis[k] + w < dis[to] || (!dis[to] && to != 1)) {
dis[to] = dis[k] + w;
if (id[to] != 0) Q.modify(id[to],mp(dis[to],to));
else id[to] = Q.push(mp(dis[to],to));
}
}
}
cout << dis[n];
return 0;
}