说在前面
写代码不够专注,然后某个2B的地方敲错了….查错半小时才过样例=A=
题目
题意
(能力不足,实在是把这个题意概括不下来…放弃了)
解法
其实仔细想想就知道,只是在最短路上多维护一个信息而已。
维护dis1[i],dis2[i]两个数组,分别表示i点的到达时间和可进入时间。那么真实的进入时间就是max( dis1[i] , dis2[i] )
用dijkstra堆优化跑最短路。
对于每次从队列里取出的u,更新它能到的点的dis1和它所保护的点的dis2,并在更新dis2的时候把deg减1,一旦有点的deg为0,就入队(注意入队不能只在更新dis2的时候判断,如果一开始某个城市的庇护数就是0,那么它的dis2永远不会被更新,也就没法入队了。我的处理方法是每次更新完后直接for一遍所有的点。当然也可以写成在更新dis1和dis2的时候都判断入队)
自带大常数的代码
/**************************************************************
Problem: 1922
User: Izumihanako
Language: C++
Result: Accepted
Time:756 ms
Memory:6504 kb
****************************************************************/
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std ;
int N , M , tp , head[3005] , deg[3005] ;
vector<int> pec[3005] ;
struct Path{
int pre , to , len ;
}p[70005] ;
struct Data{
int x ;
long long dis ;
Data(){};
Data( int x_ , long long dis_ ) :x(x_) , dis(dis_){};
bool operator < ( const Data &A ) const {
return dis > A.dis ;
}
};
void In( int t1 , int t2 , int t3 ){
p[++tp].pre = head[t1] ;
p[ head[t1] = tp ].to = t2 ;
p[tp].len = t3 ;
}
bool vis[3005] ;
priority_queue<Data> q;
long long dis1[3005] , dis2[3005] ;
void solve(){
for( int i = 1 ; i <= N ; i ++ )
dis1[i] = 1LL<<60 , dis2[i] = 0 ;
dis1[1] = dis2[1] = 0 ;
q.push( Data( 1 , 0 ) ) ;
while( !q.empty() ){
Data u = q.top() ; q.pop() ;
if( vis[u.x] ) continue ;
vis[u.x] = true ;
for( int i = head[u.x] ; i ; i = p[i].pre ){
int v = p[i].to ;
dis1[v] = min( dis1[v] , u.dis + p[i].len ) ;
// printf( "%d(%I64d) to %d(%I64d) len = %d\n" , u.x , u.dis , v , dis1[v] , p[i].len ) ;
}
for( int i = 0 , siz = pec[u.x].size() ; i < siz ; i ++ ){
int v = pec[u.x][i] ; deg[v] -- ;
dis2[v] = max( dis2[v] , u.dis ) ;
// printf( "%d(%I64d) to %d(%I64d)\n" , u.x , u.dis , v , dis2[v] ) ;
}
for( int i = 1 ; i <= N ; i ++ )
if( !vis[i] && deg[i] == 0 )
q.push( Data( i , max( dis1[i] , dis2[i] ) ) ) ;
}
printf( "%lld" , max( dis1[N] , dis2[N] ) ) ;
}
int main(){
scanf( "%d%d" , &N , &M ) ;
for( int i = 1 , u , v , w ; i <= M ; i ++ ){
scanf( "%d%d%d" , &u , &v , &w ) ;
In( u , v , w ) ;
}
for( int i = 1 ; i <= N ; i ++ ){
scanf( "%d" , °[i] ) ;
for( int j = 1 , tmp ; j <= deg[i] ; j ++ ){
scanf( "%d" , &tmp ) ;
pec[tmp].push_back( i ) ;
}
}
solve() ;
}