题目 题解 数组大小要好好算算
Code
#include <bits/stdc++.h>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair< ll, int > pa;
typedef __gnu_pbds:: priority_queue< pa, greater< pa> , pairing_heap_tag> heap;
#define mp make_pair
const int N= 400005 , M= 100002 ;
struct node{
int to, ne, w;
} e[ 1200001 ] , E[ N<< 1 ] ;
heap q;
heap:: point_iterator id[ N] ;
ll dis[ N] ;
int n, m, T, x, y, z, i, tot, h[ N] , u, TOT= 1 , in[ N<< 1 ] , out[ N<< 1 ] , top, st[ N] , S, hin[ M] , hout[ M] ;
inline char gc ( ) {
static char buf[ 100000 ] , * p1= buf, * p2= buf;
return p1== p2&& ( p2= ( p1= buf) + fread ( buf, 1 , 100000 , stdin ) , p1== p2) ? EOF : * p1++ ;
}
inline int rd ( ) {
int x= 0 , fl= 1 ; char ch= gc ( ) ;
for ( ; ch< 48 || ch> 57 ; ch= gc ( ) ) if ( ch== '-' ) fl= - 1 ;
for ( ; 48 <= ch&& ch<= 57 ; ch= gc ( ) ) x= ( x<< 3 ) + ( x<< 1 ) + ( ch^ 48 ) ;
return x* fl;
}
void ADD ( int x, int y, int z) {
E[ ++ TOT] = ( node) { y, 0 , z} , out[ TOT] = hout[ x] , in[ TOT] = hin[ y] ;
hout[ x] = hin[ y] = TOT;
}
void add ( int x, int y, int z) {
e[ ++ tot] = ( node) { y, h[ x] , z} ;
h[ x] = tot;
}
bool cmp ( int x, int y) { return E[ x] . w< E[ y] . w; }
void doit ( int x) {
top= 0 ;
for ( int i= hout[ x] ; i; i= out[ i] ) st[ top++ ] = i;
sort ( st, st+ top, cmp) ;
for ( int i= 0 ; i< top- 1 ; i++ ) add ( st[ i] , st[ i+ 1 ] , E[ st[ i+ 1 ] ] . w- E[ st[ i] ] . w) , add ( st[ i+ 1 ] , st[ i] , 0 ) ;
for ( int i= hin[ x] ; i; i= in[ i] ) add ( i, i^ 1 , E[ i] . w) ;
}
int main ( ) {
n= rd ( ) , m= rd ( ) ;
for ( i= 1 ; i<= m; i++ ) x= rd ( ) , y= rd ( ) , z= rd ( ) , ADD ( x, y, z) , ADD ( y, x, z) ;
S= ++ TOT, T= ++ TOT;
for ( i= hout[ 1 ] ; i; i= out[ i] ) add ( S, i, E[ i] . w) ;
for ( i= hin[ n] ; i; i= in[ i] ) add ( i, T, E[ i] . w) ;
for ( i= 1 ; i<= n; i++ ) doit ( i) ;
memset ( dis, 63 , ( TOT+ 1 ) << 3 ) ;
dis[ S] = 0 ;
q. push ( mp ( 0 , S) ) ;
while ( ! q. empty ( ) ) {
u= q. top ( ) . second; if ( u== T) break ; q. pop ( ) ;
for ( int i= h[ u] , v; i; i= e[ i] . ne) {
v= e[ i] . to;
if ( dis[ u] + e[ i] . w< dis[ v] ) {
dis[ v] = dis[ u] + e[ i] . w;
if ( id[ v] == 0 ) id[ v] = q. push ( mp ( dis[ v] , v) ) ;
else q. modify ( id[ v] , mp ( dis[ v] , v) ) ;
}
}
}
printf ( "%lld" , dis[ T] ) ;
}