51Nod-1671-货物运输

来源:互联网 发布:学生党淘宝店推荐不贵 编辑:程序博客网 时间:2024/05/01 08:41

ACM模版

描述

描述

题解

官方题解:

描述

首先我们需要注意到最重要的一点,所有运输方案同时进行,我们只需要计算最后到达的方案的花费时间的最小值。所以我们需要考虑的是一个极限情况,在这个极限情况下,其他运输方案全部是在允许范围内的。所以我们可以二分枚举这个极限情况,判断所有方案是否都在这个极限内,在的话就继续缩小极限,不在的话就放大极限。至于这个极限呢,涉及到传送门的位置,我们可以将传送门的位置标记为两个区间,初始化这两个区间无限大,然后通过遍历方案来不断压缩这个区间,如果所有的方案都通过后,区间依然是合法的,那么这种极限就是合法的,反之,同理。

代码

#include <cstdio>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 5e5 + 10;const int INF = 0x3f3f3f3f;int n, m;int l[MAXN], r[MAXN];bool check(int m){    int st_l = -INF, st_r = INF, ed_l = -INF, ed_r = INF;    for (int i = 1; i <= n; i++)    {        if (r[i] - l[i] <= m)        {            continue;        }        st_l = max(st_l, l[i] + r[i] - m);        st_r = min(st_r, l[i] + r[i] + m);        ed_l = max(ed_l, l[i] - r[i] - m);        ed_r = min(ed_r, l[i] - r[i] + m);        if (st_l > st_r)        {            return 0;        }        if (ed_l > ed_r)        {            return 0;        }    }    return 1;}int main(){    scanf("%d%d", &n, &m);    for (int i = 1; i <= m; i++)    {        scanf("%d%d", l + i, r + i);    }    for (int i = 1; i <= m; i++)    {        if (l[i] > r[i])        {            swap(l[i], r[i]);        }    }    int l = 0, r = n, m, ans = -1;    while (l <= r)    {        m = (l + r) >> 1;        if (check(m))        {            ans = m;            r = m - 1;        }        else        {            l = m + 1;        }    }    printf("%d\n", ans);    return 0;}
原创粉丝点击