A. 接力

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完成。样例解释完应该差不多能理解了吧。
在这里插入图片描述
所以就是能传到信号的人就会直接走,知道最后一个人结束。所以我们每次用时间最小的来传递信息。这样就不会使得乱接收了。因为时间小的肯定先到,先到肯定先传信息,先传信号也就先走,先走也就不用再走了。
大体就是,用优先队列维护最小值,一直走到最后。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=2e5+7;
ll n,sum;
ll t[maxn],vis[maxn];
ll dp[1101][1010];
#define pii pair<ll,ll>
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;
}

猜你喜欢

转载自blog.csdn.net/weixin_45911397/article/details/110433458