您的位置:首页 > 其它

2016暑期集训12C L国货物运输 HDU 5699 货物运输

2016-08-21 15:57 288 查看

L国货物运输

【问题描述】

公元2222年,L国发生了一场战争。

小Y负责领导工人运输物资。

其中有m种物资的运输方案,每种运输方案形如li, ri。表示存在一种货物从li到ri。

这里有n个城市,第i个城市与第i+1个城市相连(这里1号城市和n号城市并不相连),并且从i号城市走到i+1号或者从i+1号走到i号需要耗费1点时间。 由于高科技的存在,小Y想到了一种节省时间的好方案。在X号城市与Y号城市之间设立传送站,只要这么做,在X号城市走到Y号城市不需要耗费时间,同样的,从Y号城市走到X号城市也不需要耗费时间。

但是为了防止混乱,只能设立这么一条传送站。

现在这些运输方案同时进行,小Y想让最后到达目的地的运输方案时间最短。

在样例中,存在两条运输方案,分别是1号城市到3号与2号到4号,那么我们在2号城市与3号城市建立传送站,这样运输方案时间最长的只需要1点时间就可以了。

【输入格式】

多组测试数据

第一行两个整数n,m。

接下来m行,每行两个整数li, ri。(若li=ri, 则不需要耗费任何时间)

【输出格式】

一个数表示答案。

【样例输入】

5 2

1 3

2 4

【样例输出】

1

【样例说明】

【数据规模和约定】

1<=n, m<=1000000 1<=li, ri<=n

这道题首先具有二分性

但如何判定是个难点

我们设二分枚举的时间为x

当 x>=r[i]-l[i]时,肯定可以到达

当x<r[i]-l[i]时,得通过L R 这传送站,花费时间abs(L-l[i])+abs(R-r[i])

当我们确定L的位置时,我们也可以确定R的范围

当L<l[i] 时 R在 l[i]+r[i]-x-L r[i]-l[i]+x+L

当L>=l[i] 时 R在 r[i]-l[i]-x+L l[i]+r[i]+x-L

我们可以先枚举每一个运输,找出共同的R的范围

在确定枚举L的位置,确定R有解,即该时间下可以完成所有的运输

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int n,m;
int l[1000005],r[1000005];
int check(int x)
{
int a=0,b=1e9,c=0,d=1e9;
for (int i=1;i<=m;i++)
{
if (abs(r[i]-l[i])<=x) continue;
a=max(a,l[i]+r[i]-x);
b=min(b,l[i]+r[i]+x);
c=max(c,r[i]-l[i]-x);
d=min(d,r[i]+x-l[i]);
}
for (int i=1;i<=n;i++)
{
int L=max(i,max(a-i,c+i)),R=min(n,min(b-i,d+i));
if (L<=R) return 1;
}
return 0;
}
int ef(int st,int ed)
{
if (st==ed) return st;
int mid=(st+ed)>>1;
if (check(mid))
{
return ef(st,mid);
}else{
return ef(mid+1,ed);
}
}
int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
int maxm=0;
for (int i=1;i<=m;i++)
{
scanf("%d%d",&l[i],&r[i]);
if (l[i]>r[i]) swap(l[i],r[i]);
maxm=max(maxm,r[i]-l[i]);
}
printf("%d\n",ef(1,maxm));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二分-思考