CF1130D Toy Train

D Toy Train

  • 开始时,对于一个点 \(x\) ,若没有糖果需要运走,则不考虑;
  • 否则,若点上有 \(k\) 颗糖果需要运走,火车每次只能搭上 \(1\) 个,显然经过这个点至少 \(k\) 次.
  • 至少 \(k\) 次,说明一定转完了完整的 \(k-1\) 圈,则这个点先上车的 \(k-1\) 颗糖果一定都被送到了该送的位置.
  • 最后只需要送剩下的那个糖果 \(i\) .若出发点为 \(st\) ,则总时间为 \(S_x=dist(st,x)+n(k-1)+dist(a_i,b_i)\) .
  • 对于每个点,我们使 \(dist(a_i,b_i)\) 尽可能小.总时间花费为所有 \(\min_{1\leq x\leq n} S_x\) .
  • 预处理出每个点最小的 \(dist(a_i,b_i)\) ,每次更换起始点时对 \(n\) 个点扫一遍,时间复杂度为 \(O(n^2)\) .
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
inline int read()
{
    int x=0;
    bool pos=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar())
        if(ch=='-')
            pos=0;
    for(;isdigit(ch);ch=getchar())
        x=x*10+ch-'0';
    return pos?x:-x;
}
int n,m;
const int MAXN=2e4+10;
int dist(int x,int y)
{
    return y-x>=0?y-x:y-x+n;
}
int t[MAXN];
int midist[MAXN];
ll solve(int st)
{
    ll ans=0;
    for(int i=1;i<=n;++i)
        {
            if(midist[i])
                ans=max(ans,1LL*dist(st,i)+1LL*n*(t[i]-1)+midist[i]);
        }
    return ans;
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=m;++i)
        {
            int a=read(),b=read();
            ++t[a];
            midist[a]=midist[a]?min(midist[a],dist(a,b)):dist(a,b);
        }
    for(int i=1;i<=n;++i)
        cout<<solve(i)<<' ';
    puts("");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/jklover/p/10429005.html
今日推荐