jzoj 3187. 【GDOI2013模拟8】的士

Description

Bessie为农场上的其他奶牛提供的士服务。奶牛们在一条长为M(1<=M<=1,000,000,000)的栅栏的不同位置上。不幸的是,它们厌倦了它们现在所在的位置而想要去栅栏上其他的位置。Bessie必须把她每一个朋友从它们各自的起始地接上车然后送它们到目的地。但Bessie的车太小了,所以她每次只能运送一只奶牛。奶牛们上车下车是瞬间的事情。

为了省油钱,Bessie想要使她的驾驶量最小。给出N只奶牛(1<=N<=100,000)每一只的起始地和目的地,计算Bessie最少需要的驾驶量。Bessie意识到她需要偶尔把牛放在某一个地方而不是把它送到目的地才能省油钱。

Input

第一行输入正整数N,M

接下来N行,每行包括两个整数s_i,t_i(0<=s_i,t_i<=M),表示第i只奶牛的起始地和目的地。

Output

输出一行,Bessie最少需要的驾驶量。(注意最终结果可能会超出32位整数)

Sample Input

2 10

0 9

6 5

Sample Output

12

Data Constraint
1<=N<=100,000

Hint

在长度为10的栅栏上,有两只奶牛需要被运送。第一只想要从位置0(Bessie开始工作的地方)到位置9。第二只想要从位置6到位置5。Bessie要把第一只牛从位置0送到位置6,再把第二只牛接上来送到它的目的地位置5,然后再把第一只牛接送到它的目的地位置9,最后驾驶到栅栏的最后端结束工作。

Solution

这题我们可以分段做。其实就是差分
例如样例。
我们共有四段路径要走:
10 ~
0 9
6 5
~ 0
前后两段就是要符合:

Bessie在栅栏最左端(位置0)开始工作,而且必须在最右端(位置M)结束她的工作。

嗯,就是这样子。
然后呢,将其带入平面直角坐标系中,发现有些线段要走多次。
例如我们从6—>5,还要5—>6。
类似这样子的还有很多,我们就要以最优的路程来跑。
我们发现,可以将0—>9分解成0—>6—>9。这样子更优。
我们便将起点和终点分开来排序,然后加上∑abs(a[i]-b[i])(1≤i≤n)即可。
详细见标

Code

#include<cstdio>
#include<algorithm>
#define N 100010
#define ll long long
using namespace std;
int n,m,a[N],b[N];
ll ans=0;

inline int read()
{
	int x=0; char c=getchar();
	while (c<'0' || c>'9') c=getchar();
	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x;
}

int main()
{
//	freopen("taxi.in","r",stdin);
//	freopen("taxi.out","w",stdout);
	n=read(),m=read();
	for (int i=1;i<=n;i++)
	{
		a[i]=read(),b[i]=read();
		ans+=abs(a[i]-b[i]);
	}
	a[++n]=m,b[++n]=0;
	sort(a+1,a+n+1);
	sort(b+1,b+n+1);
	for (int i=1;i<=n;i++)
		ans+=abs(a[i]-b[i]);
	printf("%lld
",ans);
	return 0;
}
转载需注明出处。
原文地址:https://www.cnblogs.com/jz929/p/11817541.html