ural 1772

来源:互联网 发布:java 路径 编辑:程序博客网 时间:2024/06/08 01:23

有n个跑道,一开始在s跑道,有k个障碍物,问切换最少的跑道数。

当处理到第i个障碍物的时候,可以从前面没有被遮挡的端点来转移,并且肯定是最近的端点来转移的,用set来维护。

找到转移点后把该障碍物遮挡的点全部给删除掉。

最后找到从哪条跑道上的极小值输出答案。

#include <cstdio>#include <cstring>#include <set>#include <vector>using namespace std;const int maxn = 100007;const long long INF = 50007ll * 50000ll * 50000ll;set<int> point;set<int>::iterator pre, last, cnt;vector<int> point_to_erase;long long dp[maxn];int main() {//    freopen("in.txt", "r", stdin);    int n, s, k;    scanf("%d%d%d", &n, &s, &k);    point.insert(0);    point.insert(n + 1);    point.insert(s);    for (int i = 0; i <= n + 1; i++) {        dp[i] = INF;    }    dp[s] = 0;    while (k--) {        int a, b;        scanf("%d%d", &a, &b);        if (a > 1) {            a--;            point.insert(a);            cnt = point.find(a);            int loc_1 = *cnt;            int loc_2, loc_3;            pre = --cnt;            cnt++;            last = ++cnt;            loc_2 = *pre;            loc_3 = *last;            long long temp = dp[loc_2] + loc_1 - loc_2;            if (temp < dp[loc_1]) {                dp[loc_1] = temp;            }            temp = dp[loc_3] + loc_3 - loc_1;            if (temp < dp[loc_1]) {                dp[loc_1] = temp;            }            a++;        }        if (b < n) {            b++;            point.insert(b);            cnt = point.find(b);            int loc_1 = *cnt;            int loc_2, loc_3;            pre = --cnt;            cnt++;            last = ++cnt;            loc_2 = *pre;            loc_3 = *last;            long long temp = dp[loc_2] + loc_1 - loc_2;            if (temp < dp[loc_1]) {                dp[loc_1] = temp;            }            temp = dp[loc_3] + loc_3 - loc_1;            if (temp < dp[loc_1]) {                dp[loc_1] = temp;            }            b--;        }        point_to_erase.clear();        for (cnt = point.lower_bound(a); cnt != point.end() && (*cnt) <= b; cnt++) {            point_to_erase.push_back(*cnt);        }        for (int i = 0; i < point_to_erase.size(); i++) {            dp[point_to_erase[i]] = INF;            point.erase(point_to_erase[i]);        }    }    long long ans = INF;    for (int i = 1; i <= n; i++) {        if (ans > dp[i]) {            ans = dp[i];        }    }    printf("%I64d\n", ans);    return 0;}

0 0