A. 接力

接力共有n名队员(编号1−n)参加,在同一时刻赛道上允许有任意多名选手同时赛跑。比赛开始前,所有交警在起跑线等待起跑。
在t=0时刻,编号为1的选手开始赛跑,L1秒后跑完一圈回到起点。当选手i跑完一圈他会示意Mi名选手开始接力。(选手可能被多次示意,只算最早的示意)每个选手只跑一圈。
接力的总时间为最后一个选手结束赛跑的时间。求接力的总时间。

Input
第一行一个单独的整数n,表示有n名选手。
接下来n行,每行开始有2个整数Li,Mi,接下来有Mi个整数,表示示意选手的编号。

Output
一行一个整数,表示接力的总时间。

Samples
Input Copy
5
4 2 2 4
3 3 1 3 4
7 1 5
4 2 3 5
1 0
Output
14
Hint
【数据范围与约定】

对于30%的数据:n≤10。
对于60%的数据:n≤300。
对于100%的数据:n≤1000。
Source
石光中学 2017长乐暑期集训第6套
题意:
在同一时刻赛道上允许有任意多名选手同时赛跑。 注意这句话,他其实就是只要有人给他信号让他跑他就会跑。(没跑过)
问全部跑完用多长时间。

思路:

一开始读错题意了,我理解的样例就是凑出来的。其实不然

先解释下样例。

先是1接受到信号,走了4秒,之后把信号传给2和4,然后2和4一起跑,2先跑完,2将信号传给1(已走不接收),3和4(已走不接收),然后4跑完了,传给2(已走),3(已走)和5(已走),所以他就传不出去,就等3完成。样例解释完应该差不多能理解了吧。

A. 接力_i++


所以就是能传到信号的人就会直接走,知道最后一个人结束。所以我们每次用时间最小的来传递信息。这样就不会使得乱接收了。因为时间小的肯定先到,先到肯定先传信息,先传信号也就先走,先走也就不用再走了。

大体就是,用优先队列维护最小值,一直走到最后。

#include<bits/stdc++.h>
using namespace std;
#define
const int maxn=2e5+7;
ll n,sum;
ll t[maxn],vis[maxn];
ll dp[1101][1010];
#define
void bfs() {
priority_queue<pii,vector<pii>,greater<pii> >q;
pii p;
p= {t[1],1};
vis[1]=1;
q.push(p);
while(!q.empty()) {
pii top=q.top();
q.pop();

ll ans=top.first;
ll x=top.second;

sum=max(ans,sum);
for(int i=1; i<=dp[x][0]; i++) {
if(vis[dp[x][i]]==0) {
vis[dp[x][i]]=1;
p= {ans+t[dp[x][i]],dp[x][i]};
q.push(p);
}
}
}
}
int main() {
cin>>n;
for(int i=1; i<=n; i++) {
cin>>t[i];
ll m;
cin>>m;
for(int j=1; j<=m; j++) {
ll y;
scanf("%lld",&y);
dp[i][++dp[i][0]]=y;
}
}
bfs();
cout<<sum<<endl;
return 0;
}