Follow the Penguins

题意:

给定若干个点,它们有一个要追赶的点和当前位置,求最后所有点停止的时间,(一个点移动的速度为0.5)

思路:

使用set模拟优先队列

求出每个点移动的方向(一定不变了)

存一个pair<当前点和追赶点的距离 即time(相向而行时time=dis/2),当前点>

第一个停的点一定是相向而行的点

把所有以这个点为目标的点距离计算一下

避免精度丢失位置要乘2

int n;
const int M=5e5+5;
int t[M];
int a[M];
int dir[M];

vector<int>bt[M];
int ans[M];
int npos[M];
void solve(){
    cin>>n;
    rep(i,1,n)cin>>t[i],bt[t[i]].pb(i);
    rep(i,1,n)cin>>a[i],a[i]*=2;

    rep(i,1,n){
        int j=t[i];
        if(a[i]>a[j])dir[i]=-1;
        else dir[i]=1;
    }

    set<pii>s;
    rep(i,1,n){
        if(dir[i]!=dir[t[i]]){
            s.insert({abs(a[i]-a[t[i]])>>1 ,i});
        }
    }

    while(s.size()){
        auto[time,x]=*s.begin();
        s.erase(s.begin());

        if(ans[x])continue;
        ans[x]=time;

        npos[x]=a[x]+dir[x]*time;
        
        for(auto y:bt[x]){
            s.erase( { abs(a[y]-a[t[y]])>>1 ,y } );
            s.insert( { abs(a[y]-npos[x]), y } );//为什么y不用计算time时刻的位置?因为x一定先比y停,y此时需要追赶的就是一开始的位置和npos[x]的距离差
        }
    }
    rep(i,1,n){
        cout<<ans[i]<<' ';
    }
    cout<<endl;
}
posted @ 2025-11-10 17:22  Marinaco  阅读(11)  评论(0)    收藏  举报
//雪花飘落效果