You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
const int N = 10010 , M = N < < 1 , K = 110 ;
// 链式前向星
int e [ M ] , h [ N ] , idx , w [ M ] , ne [ M ] ;
void add ( int a , int b , int c = 0 ) {
e [ idx ] = b , ne [ idx ] = h [ a ] , w [ idx ] = c , h [ a ] = idx + + ;
}
// 入队列的结构体
struct Node {
int id ; // 节点号
int r ; // %k的余数
} ;
int dis [ N ] [ K ] ; // 最短路径
int n , m , k ; // n个节点, m条边, 时间是k的整数倍, 即 %k=0
bool bfs ( int mid ) {
memset ( dis , - 1 , sizeof dis ) ;
queue < Node > q ;
dis [ n ] [ 0 ] = mid * k ;
q . push ( { n , 0 } ) ;
while ( q . size ( ) ) {
int u = q . front ( ) . id ;
int r = q . front ( ) . r ;
q . pop ( ) ;
if ( dis [ u ] [ r ] = = 0 ) continue ; // 反着走, 距离为0, 就不需要继续走了,剪枝
for ( int i = h [ u ] ; ~ i ; i = ne [ i ] ) {
int v = e [ i ] ; // 前序节点
int p = ( r - 1 + k ) % k ; // 前序节点合法状态
if ( ~ dis [ v ] [ p ] ) continue ; // 如果前序点的合法状态不等于-1, 表示已经被宽搜走过了, 根据宽搜的理论, 就是已经取得了最短距离, 不需要再走
if ( dis [ u ] [ r ] - 1 < w [ i ] ) continue ; // 现在的最短距离是dis[u][r],那么前序的距离应该是dis[u][r]-1,那么, 如果dis[u][r]-1<w[i],就是表示到达时,开放时间未到,无法能行
// 修改合法前序点距离, 为当前最小距离减1
dis [ v ] [ p ] = dis [ u ] [ r ] - 1 ;
// 入队列继续扩展
q . push ( { v , p } ) ;
}
}
if ( dis [ 1 ] [ 0 ] = = - 1 )
return false ;
else
return true ;
}
int main ( ) {
memset ( h , - 1 , sizeof h ) ;
cin > > n > > m > > k ;
while ( m - - ) {
int a , b , c ;
cin > > a > > b > > c ;
add ( b , a , c ) ;
}
int l = 0 , r = ( 1e6 + 1e4 ) / k , ans = - 1 ;
while ( l < r ) {
int mid = l + r > > 1 ;
if ( bfs ( mid ) ) {
ans = mid * k ;
r = mid ;
} else
l = mid + 1 ;
}
cout < < ans < < endl ;
return 0 ;
}