版权声明:版权所有,转载请标明博文出处。 https://blog.csdn.net/HQG_AC/article/details/84526679
题意:
小J(jack)要从1穿越到n。星球之间有一些双向通道,小J可以通过这些通道到达n。
但是有一些霸道的穿越者也要穿越。
当小J和穿越者同时要从S到T时,他必须要等待该穿越者出发才能出发,花费一秒。
如果有多个穿越者,那么必须等这些穿越者全部出发,小J才能出发
问最短要多久才能到达n
分析:
一看就是一个最短路模板题。我们就想怎么处理等待。
我们能够出发的时间是该点之后第一个没有被标记有穿越者来的那个点。
于是就暴力往后找。
可能时间复杂度有Bug,但是在CF下过了。速度也不慢。
最短路是写Dijkstra的。
如果要提高效率,可以再set中进行二分查找。这样很快。
代码:
#include <bits/stdc++.h>
using namespace std ;
#define rep(i, a, b) for (int (i) = (a); (i) <= (b); (i)++)
#define Rep(i, a, b) for (int (i) = (a) - 1; (i) < (b); (i)++)
#define REP(i, a, b) for (int (i) = (a); (i) >= (b); (i)--)
#define clr(a) memset(a, 0, sizeof(a))
#define Sort(a, len, cmp) sort(a + 1, a + len + 1, cmp)
#define ass(a, sum) memset(a, sum, sizeof(a))
#define ls ((rt) << 1)
#define rs ((rt) << 1 | 1)
#define lowbit(x) (x & -x)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define endl '\n'
#define ENDL cout << endl
#define SZ(x) ((int)x.size())
typedef long long ll ;
typedef unsigned long long ull ;
typedef vector <int> Vi ;
typedef pair <int, int> Pii ;
typedef pair <ll, ll> Pll ;
typedef map <int, int> mii ;
typedef map <string, int> msi ;
typedef map <ll, ll> mll ;
const int N = 100010 ;
const double eps = 1e-8 ;
const int iinf = INT_MAX ;
const ll linf = 2e18 ;
const double dinf = 1e30 ;
const int MOD = 1000000007 ;
int n, m, top = 1 ;
set <int> s[N] ;
int dis[N], head[N] ;
struct edge {
int to, nxt, w ;
} e[N << 1] ;
void add(int a, int b, int w) {
e[++top] = (edge) {b, head[a], w} ;
head[a] = top ;
}
struct node {
int x, len ;
bool operator < (const node &a) const {
return len > a.len ;
}
};
void dij() {
priority_queue <node> q ;
for (int i = 1; i <= n; i++) dis[i] = iinf ;
dis[1] = 0 ;
q.push((node) {1, 0}) ;
while (!q.empty()) {
node now = q.top() ;
q.pop() ;
int tim = now.len ;
while (s[now.x].count(tim)) tim++ ;
if (dis[now.x] != now.len) continue ;
for (int i = head[now.x]; i; i = e[i].nxt) {
int to = e[i].to ;
if (dis[to] > tim + e[i].w) {
dis[to] = tim + e[i].w ;
q.push((node) {to, dis[to]}) ;
}
}
}
}
signed main(){
scanf("%d%d", &n, &m) ;
for (int i = 1; i <= m; i++) {
int x, y, z ;
scanf("%d%d%d", &x, &y, &z) ;
add(x, y, z) ;
add(y, x, z) ;
}
for (int i = 1; i <= n; i++) {
int sum, x ;
scanf("%d", &sum) ;
while (sum--) scanf("%d", &x), s[i].insert(x) ;
}
dij() ;
if (dis[n] == iinf) cout << -1 << endl ;
else cout << dis[n] << endl ;
return 0 ;
}