Planets CodeForces - 230D

Goa’uld Apophis captured Jack O’Neill’s team again! Jack himself was able to escape, but by that time Apophis’s ship had already jumped to hyperspace. But Jack knows on what planet will Apophis land. In order to save his friends, Jack must repeatedly go through stargates to get to this planet.

Overall the galaxy has n planets, indexed with numbers from 1 to n. Jack is on the planet with index 1, and Apophis will land on the planet with index n. Jack can move between some pairs of planets through stargates (he can move in both directions); the transfer takes a positive, and, perhaps, for different pairs of planets unequal number of seconds. Jack begins his journey at time 0.

It can be that other travellers are arriving to the planet where Jack is currently located. In this case, Jack has to wait for exactly 1 second before he can use the stargate. That is, if at time t another traveller arrives to the planet, Jack can only pass through the stargate at time t + 1, unless there are more travellers arriving at time t + 1 to the same planet.

Knowing the information about travel times between the planets, and the times when Jack would not be able to use the stargate on particular planets, determine the minimum time in which he can get to the planet with index n.

Input
The first line contains two space-separated integers: n (2 ≤ n ≤ 105), the number of planets in the galaxy, and m (0 ≤ m ≤ 105) — the number of pairs of planets between which Jack can travel using stargates. Then m lines follow, containing three integers each: the i-th line contains numbers of planets ai and bi (1 ≤ ai, bi ≤ n, ai ≠ bi), which are connected through stargates, and the integer transfer time (in seconds) ci (1 ≤ ci ≤ 104) between these planets. It is guaranteed that between any pair of planets there is at most one stargate connection.

Then n lines follow: the i-th line contains an integer ki (0 ≤ ki ≤ 105) that denotes the number of moments of time when other travellers arrive to the planet with index i. Then ki distinct space-separated integers tij (0 ≤ tij < 109) follow, sorted in ascending order. An integer tij means that at time tij (in seconds) another traveller arrives to the planet i. It is guaranteed that the sum of all ki does not exceed 105.

Output
Print a single number — the least amount of time Jack needs to get from planet 1 to planet n. If Jack can’t get to planet n in any amount of time, print number -1.

Examples

Input
4 6
1 2 2
1 3 3
1 4 8
2 3 4
2 4 5
3 4 3
0
1 3
2 3 4
0
Output
7

Input
3 1
1 2 3
0
1 3
0
Output
-1

Note
In the first sample Jack has three ways to go from planet 1. If he moves to planet 4 at once, he spends 8 seconds. If he transfers to planet 3, he spends 3 seconds, but as other travellers arrive to planet 3 at time 3 and 4, he can travel to planet 4 only at time 5, thus spending 8 seconds in total. But if Jack moves to planet 2, and then — to planet 4, then he spends a total of only 2 + 5 = 7 seconds.

In the second sample one can’t get from planet 1 to planet 3 by moving through stargates.

题意:给你n个点和m条边,每条边有一个通过时间,在每个点上有几个值,表示不能在这个时间点通过,如果在这个时间到达了这个点,需要等待1个单位的时间。例如:在第3秒到达,第3秒又不能通过,只能等待1秒,在第4秒才能通过。从第1个点出发,到达第n个点,最少需要多少时间?

思路:我们用spfa或dijkstra跑一边最短路,每当我们到达一个点时,我们就查询一下这个点什么时候不能走,如果恰好不能走,更新时多加时长。

#include<iostream>
#include<cstring>
#include<queue>
#include<set>
using namespace std;
const int maxn=1e6+9;
int head[maxn],dis[maxn],book[maxn],n,m,cnt;
set<int > s[maxn];
struct node{
	int id;
	int val;
	int next;
}side[maxn];
void init()
{
	memset(head,-1,sizeof(head));
	memset(dis,0x3f3f3f3f,sizeof(dis));
	memset(book,0,sizeof(book));
	cnt=0;
}
void add(int x,int y,int d)
{
	side[cnt].id=y;
	side[cnt].val=d;
	side[cnt].next=head[x];
	head[x]=cnt++;
}
int solve(int num,int id)
{
	while(s[id].find(num)!=s[id].end())
	{
		num++;
	}
	return num;
}
void spfa(int sx)
{
	queue<int> q;
	dis[sx]=0;book[sx]=1;
	q.push(sx);
	while(q.size())
	{
		int x=q.front();
		book[x]=0;
		q.pop();
		int tmp=solve(dis[x],x);
		for(int i=head[x];i!=-1;i=side[i].next)
		{
			int y=side[i].id;
			if(dis[y]>tmp+side[i].val)
			{
				dis[y]=tmp+side[i].val;
				if(!book[y])
				{
					book[y]=1;
					q.push(y);
				}
			}
		}
	}
}
int main()
{
	int a,b,c,k;
	cin>>n>>m;
	init();
	for(int i=1;i<=m;i++)
	{
		cin>>a>>b>>c;
		add(a,b,c);
		add(b,a,c);
	}
	for(int i=1;i<=n;i++)
	{
		cin>>a;
		for(int j=1;j<=a;j++)
		{
			cin>>b;
			s[i].insert(b);
		}
	}
	spfa(1);
	if(dis[n]==0x3f3f3f3f)
        cout<<-1<<endl;
    else
        cout<<dis[n]<<endl;
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值