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;
}

相关文章:

  • 2021-12-06
  • 2021-11-21
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-19
  • 2021-11-10
猜你喜欢
  • 2022-12-23
  • 2021-07-02
  • 2021-05-27
  • 2022-12-23
  • 2022-03-02
  • 2021-08-26
  • 2021-09-05
相关资源
相似解决方案